首先我们来看下我们整个流程图
这就是我自己摸索出来的关于整个访问拦截登录重定向的流程图 其中3,6,7步是对拦截前访问的request的处理
接下来是对以上几个步骤中关键代码的分析
1.
首先我们先了解下关于
FilterSecurityIntercepto所在的位置
我们看到他在最后一位从这个拦截器的下面代码:
// Attempt authorization
try {
this.accessDecisionManager .decide(authenticated , object , attributes );
}
catch (AccessDeniedException accessDeniedException ) {
publishEvent( new AuthorizationFailureEvent(object , attributes , authenticated, accessDeniedException ));
throw accessDeniedException;
}
2.
我们能够看出当其在身份的权限验证失败的情况下会抛出
accessDeniedException异常,这个时候上一层的拦截器也就是倒数第二个拦截器ExceptionTranslationFilter捕获了该异常并进一步处理具体代码如下
private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response , FilterChain chain,
RuntimeException exception) throws IOException, ServletException {
if (exception instanceof AuthenticationException) {
logger.debug( "Authentication exception occurred; redirecting to authentication entry point", exception);
sendStartAuthentication( request, response, chain, (AuthenticationException) exception );
}
else if (exception instanceof AccessDeniedException ) {
if (authenticationTrustResolver .isAnonymous(SecurityContextHolder.getContext().getAuthentication())) {
logger.debug( "Access is denied (user is anonymous); redirecting to authentication entry point",
exception);
sendStartAuthentication( request, response, chain, new InsufficientAuthenticationException(
"Full authentication is required to access this resource"));
}
else {
logger.debug( "Access is denied (user is not anonymous); delegating to AccessDeniedHandler", exception);
accessDeniedHandler.handle(request , response , (AccessDeniedException) exception);
}
}
}
3.
进入
sendStartAuthentication这个函数后我们看到了
protected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response , FilterChain chain,
AuthenticationException reason) throws ServletException, IOException {
// SEC-112: Clear the SecurityContextHolder's Authentication, as the
// existing Authentication is no longer considered valid
SecurityContextHolder. getContext().setAuthentication(null);
requestCache.saveRequest(request , response );
logger.debug( "Calling Authentication entry point." );
authenticationEntryPoint.commence(request , response , reason );
}
这里就有
requ