SpringSecurity过滤器之SecurityContextHolderAwareRequestFilter,RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
SecurityContextHolderAwareRequestFilter对Servelet3.0的api做了封装。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(this.requestFactory.create((HttpServletRequest) req, (HttpServletResponse) res), res);
}
requestFactory是HttpServlet3RequestFactory。
HttpServlet3RequestFactory#create
public HttpServletRequest create(HttpServletRequest request, HttpServletResponse response) {
return new Servlet3SecurityContextHolderAwareRequestWrapper(request, this.rolePrefix, response);
}
rolePrefix是ROLE_。用于添加角色前缀。
private class Servlet3SecurityContextHolderAwareRequestWrapper extends SecurityContextHolderAwareRequestWrapper {
private final HttpServletResponse response;
Servlet3SecurityContextHolderAwareRequestWrapper(HttpServletRequest request, String rolePrefix,
HttpServletResponse response) {
super(request, HttpServlet3RequestFactory.this.trustResolver, rolePrefix);
this.response = response;
}
@Override
public AsyncContext getAsyncContext() {
AsyncContext asyncContext = super.getAsyncContext();
if (asyncContext == null) {
return null;
}
return new SecurityContextAsyncContext(asyncContext);
}
@Override
public AsyncContext startAsync() {
AsyncContext startAsync = super.startAsync();
return new SecurityContextAsyncContext(startAsync);
}
@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException {
AsyncContext startAsync = super.startAsync(servletRequest, servletResponse);
return new SecurityContextAsyncContext(startAsync);
}
@Override
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
AuthenticationEntryPoint entryPoint = HttpServlet3RequestFactory.this.authenticationEntryPoint;
if (entryPoint == null) {
HttpServlet3RequestFactory.this.logger.debug(
"authenticationEntryPoint is null, so allowing original HttpServletRequest to handle authenticate");
return super.authenticate(response);
}
if (isAuthenticated()) {
return true;
}
entryPoint.commence(this, response,
new AuthenticationCredentialsNotFoundException("User is not Authenticated"));
return false;
}
@Override
public void login(String username, String password) throws ServletException {
if (isAuthenticated()) {
throw new ServletException("Cannot perform login for '" + username + "' already authenticated as '"
+ getRemoteUser() + "'");
}
AuthenticationManager authManager = HttpServlet3RequestFactory.this.authenticationManager;
if (authManager == null) {
HttpServlet3RequestFactory.this.logger.debug(
"authenticationManager is null, so allowing original HttpServletRequest to handle login");
super.login(username, password);
return;
}
Authentication authentication = getAuthentication(authManager, username, password);
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
}
private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
throws ServletException {
try {
UsernamePasswordAuthenticationToken authentication = UsernamePasswordAuthenticationToken
.unauthenticated(username, password);
Object details = HttpServlet3RequestFactory.this.authenticationDetailsSource.buildDetails(this);
authentication.setDetails(details);
return authManager.authenticate(authentication);
}
catch (AuthenticationException ex) {
SecurityContextHolder.clearContext();
throw new ServletException(ex.getMessage(), ex);
}
}
@Override
public void logout() throws ServletException {
List<LogoutHandler> handlers = HttpServlet3RequestFactory.this.logoutHandlers;
if (CollectionUtils.isEmpty(handlers)) {
HttpServlet3RequestFactory.this.logger
.debug("logoutHandlers is null, so allowing original HttpServletRequest to handle logout");
super.logout();
return;
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
for (LogoutHandler handler : handlers) {
handler.logout(this, this.response, authentication);
}
}
private boolean isAuthenticated() {
return getUserPrincipal() != null;
}
}
Servlet3SecurityContextHolderAwareRequestWrapper对Servlet3.0的方法做了封装。方法中有AsyncContext的是与异步web相关。对Servlet3.0的登录,登出,认证方法都做了封装。父类SecurityContextHolderAwareRequestWrapper重写了HttpServletRequestWrapper的getUserPrincipal(),isUserInRole(String),getRemoteUser()。
RequestCacheAwareFilter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest wrappedSavedRequest = this.requestCache.getMatchingRequest((HttpServletRequest) request,
(HttpServletResponse) response);
chain.doFilter((wrappedSavedRequest != null) ? wrappedSavedRequest : request, response);
}
如果在requestCache有保存的请求直接用否则用ServletRequest。默认是HttpSessionRequestCache。将SavedRequest保存到Session中。