java如何在SpringSecurity中为特殊情况下的身份验证失败定制http状态代码?
我正在编写一个RESTful服务,没有用户界面,因此没有错误页面。当我得到一个过期的令牌时,我想设置一个特定的错误代码和消息,以便调用者知道它需要再次登录。(我不担心给黑客提供额外的信息,因为我只在令牌具有正确的数字签名时看到这种情况。)我试过三种不同的方法
- 抛出CredentialsExpiredException,它扩展了AuthenticationException。我已经安装了一个
AuthenticationEntryPoint
来处理异常,但是SpringSecurity向它发送了一个不同的异常。因此,无法区分自定义失败和标准身份验证拒绝李> - 抛出一个用
@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
注释的自定义异常。 这应该会生成一个417的错误代码,但我得到一个403。我还尝试添加一个用@ControllerAdvice
注释的类,但没有效果李> - 我在
SecurityContext
中设置了一个UsernamePasswordAuthenticationToken
,但凭证列表为空。这将生成与任何其他故障模式具有相同403 Http状态的响应。无法指定不同的状态代码或消息李>
我将我的AuthenticationEntryPoint
安装到我的WebSecurity配置中,如下所示:
@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进行尝试 自述。md文件解释了如何使用它,并记录了它实现的端点。它使用Java12,但代码将在Java8下编译
(我知道身份验证失败通常不会返回太多信息,以避免给黑客提供任何有用的信息,但我只想告诉用户,他们的JWT令牌已过期,他们需要重新登录。上面的测试用例不使用JWT,因为不必重现问题。)
# 1 楼答案
我从未找到更改HttpStatus代码的方法,但我确实找到了通知调用方令牌已过期的方法。当我检测到过期令牌时,我会在响应中添加一个指定过期令牌的头。这不完全是我想要的,但它做到了
有一次,我能够使用这个头来更改AuthenticationEntryPoint类中的响应代码。但我又试了一次,结果没用。我不知道我改变了什么来打破这个,但这无关紧要