我正在编写一个restful服务,没有用户界面,因此没有错误页。当我得到一个过期的令牌时,我想设置一个特定的错误代码和消息,以便调用者知道它需要再次登录(我不担心给黑客提供额外的信息,因为我只在令牌具有正确的数字签名时才会看到这种情况。)我尝试了三种不同的方法。
抛出credentialsexpiredexception,它扩展authenticationexception。我安装了一个 AuthenticationEntryPoint
但Spring Security 会向它发送一个不同的异常。因此,无法区分自定义失败和标准身份验证拒绝。
抛出一个自定义异常,用 @ResponseStatus(HttpStatus.EXPECTATION_FAILED)
. 这应该会产生一个错误代码417,但我得到一个403禁止。我还尝试添加一个用 @ControllerAdvice
,但这没有效果。
我设置了一个 UsernamePasswordAuthenticationToken
进入 SecurityContext
,但凭据列表为空。这将生成与任何其他故障模式具有相同403 http状态的响应。无法指定其他状态代码或消息。
我安装我的 AuthenticationEntryPoint
我的网络安全配置如下:
@SuppressWarnings("HardcodedFileSeparator")
@Override
protected void configure(final HttpSecurity http) throws Exception {
log.trace("Configuring WebSecurityConfig");
/* The /view/**path requires no authentication. The others start with /admin, and require the ADMIN role. */
http
.csrf()
.disable()
.cors()
.disable()
.formLogin()
.disable()
.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/view/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.addFilterBefore(requestFilter, UsernamePasswordAuthenticationFilter.class)
;
}
我在上面最后一行中安装的requestfilter是抛出异常的地方,我认为异常会被发送到 AuthenticationEntryPoint
.
我不知道为什么 @ResponseStatus
注解不起作用。我不知道如何在SpringSecurity中设置特定的错误代码。
我已经创建了一个最小的可复制的测试用例,您可以在https://github.com/swingguy1024/securityquestion readme.md文件解释了如何使用它并记录了它实现的端点。它使用Java12,但代码将在Java8下编译。
(我知道身份验证失败通常不应该返回太多信息,以避免向黑客提供任何有用的信息,但我只想告诉用户,他们的jwt令牌已过期,他们需要重新登录。上面的测试用例没有使用jwt,因为没有必要重现问题。)
1条答案
按热度按时间js4nwp541#
我从未找到更改httpstatus代码的方法,但我确实找到了通知调用方令牌已过期的方法。当我检测到过期令牌时,我会在响应中添加一个指定过期令牌的头。这不完全是我想要的,但它确实奏效了。
有一次,我可以使用这个头来更改authenticationentrypoint类中的响应代码。但我又试了一次,结果没用。我不知道我换了什么来打破这个,但没关系。