Java Spring安全性:用于验证密码过期错误处理的OAuth2自定义筛选器
我一直在尝试实现OAuth2密码过期过滤器,我不确定正确的方法是什么。其思路如下:Java Spring安全性:用于验证密码过期错误处理的OAuth2自定义筛选器,java,spring,spring-security,spring-boot,spring-security-oauth2,Java,Spring,Spring Security,Spring Boot,Spring Security Oauth2,我一直在尝试实现OAuth2密码过期过滤器,我不确定正确的方法是什么。其思路如下: 用户尝试登录 如果密码过期,用户将获得包含令牌的标头响应 用户get使用该令牌(即/password change/{token})重定向到密码更改页面 他提交了他的新旧密码,密码被更改了 某些rest控制器通过该令牌检索用户id,并执行rest密码更改逻辑 应将用户重定向回初始登录页面,在该页面上他使用新密码登录(如果他在密码更改后立即登录,即使由于某些异常等原因密码不会在后台更改,他也可以在安全页面中导航)
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
...
http.addFilterAfter(new PasswordExpirationFilter(), BasicAuthenticationFilter.class
}
}
好的,我想我解决了这个问题,通过在我的过滤器中注入TokenStore(我使用BearerTokenExtractor来获取令牌值)来撤销访问令牌,这在这种情况下似乎非常合理。我还没来得及弄清楚,为什么我的过滤器放在OAuth2AuthenticationProcessingFilter之后。噢,我认为更合适的方法是在获得oauth2令牌之前进行整个过期密码验证。我只需要在已经建立的身份验证机制上快速完成这项工作。
public class PasswordExpirationFilter extends OncePerRequestFilter implements Filter, InitializingBean {
private static final String TOKEN_HEADER = ...;
private ExpiredPasswordRepository repo; // gets set in a constructor and is basically holding a concurrent map of tokens
...
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
UserDetails details = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (details.isPasswordExpired) {
String uuid = UUID.randomUUID().toString();
repo.push(uuid, details.getId());
SecurityContextHolder.clearContext();
SecurityContextHolder.getContext().setAuthentication(null);
request.getSession(false).invalidate(); // don't create a new session
response.addHeader(TOKEN_HEADER, uuid);
response.sendError(HttpStatus.SC_PRECONDITION_FAILED, "Credentials have expired");
} else {
filterChain.doFilter(request, response);
}
}
}