- 浏览: 1193939 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
insistboy:
写的太棒了,受不了
WebLogic11g-创建域(Domain) -
goldyeah:
厉害了 困扰我大半个月的问题解决了 谢谢博主
WebLogic11g-单双向SSL配置(以Springside3为例) -
zy315351965:
404伤不起
开源流程引擎Snaker -
nannan408:
双向的时候谷歌提示“不接受您的登录证书,或者您可能没有提供登录 ...
WebLogic11g-单双向SSL配置(以Springside3为例) -
一颗赛艇:
不成功啊。启动有问题 <Security> < ...
WebLogic11g-单双向SSL配置(以Springside3为例)
ExceptionTranslationFilter过滤器对应的类路径为
org.springframework.security.web.access.ExceptionTranslationFilter
从类名就看出这个过滤器用于异常翻译的。但是从这个过滤器在filterchain中的位置来看,它仅仅处于倒数第三的位置(这个filter后面分为是FilterSecurityInterceptor、SwitchUserFilter),所以ExceptionTranslationFilter只能捕获到后面两个过滤器所抛出的异常。
这里需要强调一下,spring security中的异常类基本上都继承RuntimeException。
接着看ExceptionTranslationFilter执行过程
先分析如何处理认证异常
这里补充一下
authenticationEntryPoint是由配置http标签时,通过什么认证入口来决定注入相应的入口点bean的。请看下面的对应关系列表
form-login认证:LoginUrlAuthenticationEntryPoint
http-basic认证:BasicAuthenticationEntryPoint
openid-login认证:LoginUrlAuthenticationEntryPoint
x509认证:Http403ForbiddenEntryPoint
就不一一分析每个EntryPoint了,着重看一下LoginUrlAuthenticationEntryPoint
接着分析访问拒绝类异常的处理过程,看AccessDeniedHandlerImpl的handle方法
通过以上分析,可以大体上认识到ExceptionTranslationFilter主要拦截两类安全异常:认证异常、访问拒绝异常。而且仅仅是捕获FilterSecurityInterceptor、SwitchUserFilter以及自定义拦截器的异常。所以在自定义拦截器时,需要注意在链中的顺序。
在上面分析过程中,有requestCache.saveRequest(request, response);的语句,具体requestCache的用途下篇分析。
org.springframework.security.web.access.ExceptionTranslationFilter
从类名就看出这个过滤器用于异常翻译的。但是从这个过滤器在filterchain中的位置来看,它仅仅处于倒数第三的位置(这个filter后面分为是FilterSecurityInterceptor、SwitchUserFilter),所以ExceptionTranslationFilter只能捕获到后面两个过滤器所抛出的异常。
这里需要强调一下,spring security中的异常类基本上都继承RuntimeException。
接着看ExceptionTranslationFilter执行过程
//doFilter拦截到请求时,不做处理。仅仅处理后面filter所抛出的异常 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try { chain.doFilter(request, response); } catch (IOException ex) { throw ex; } catch (Exception ex) { //这里主要是从异常堆栈中提取SpringSecurityException Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex); RuntimeException ase = (AuthenticationException) throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain); if (ase == null) { ase = (AccessDeniedException)throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain); } //如果提取到安全异常,则进行处理 if (ase != null) { handleException(request, response, chain, ase); } else { //没有安全异常,继续抛出 // Rethrow ServletExceptions and RuntimeExceptions as-is if (ex instanceof ServletException) { throw (ServletException) ex; } else if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } throw new RuntimeException(ex); } } } //处理安全异常 private void handleException(HttpServletRequest request, HttpServletResponse response, FilterChain chain, RuntimeException exception) throws IOException, ServletException { //如果是认证异常,由sendStartAuthentication处理 if (exception instanceof AuthenticationException) { sendStartAuthentication(request, response, chain, (AuthenticationException) exception); } //如果是访问拒绝异常,由访问拒绝处理类的handle处理 else if (exception instanceof AccessDeniedException) { if (authenticationTrustResolver.isAnonymous(SecurityContextHolder.getContext().getAuthentication())) { sendStartAuthentication(request, response, chain, new InsufficientAuthenticationException( "Full authentication is required to access this resource")); } else { accessDeniedHandler.handle(request, response, (AccessDeniedException) exception); } } }
先分析如何处理认证异常
//处理认证异常 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 //首先把SecurityContext中的认证实体置空 SecurityContextHolder.getContext().setAuthentication(null); //通过cache保存当前的请求信息(分析RequestCacheAwareFilter时再深入) requestCache.saveRequest(request, response); logger.debug("Calling Authentication entry point."); //由认证入口点开始处理 authenticationEntryPoint.commence(request, response, reason); }
这里补充一下
authenticationEntryPoint是由配置http标签时,通过什么认证入口来决定注入相应的入口点bean的。请看下面的对应关系列表
form-login认证:LoginUrlAuthenticationEntryPoint
http-basic认证:BasicAuthenticationEntryPoint
openid-login认证:LoginUrlAuthenticationEntryPoint
x509认证:Http403ForbiddenEntryPoint
就不一一分析每个EntryPoint了,着重看一下LoginUrlAuthenticationEntryPoint
//主要目的是完成跳转任务 //创建该bean时,只注入了loginFormUrl属性,其他类变量均为默认值 public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String redirectUrl = null; //默认为false if (useForward) { if (forceHttps && "http".equals(request.getScheme())) { redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest); } if (redirectUrl == null) { String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException); RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm); dispatcher.forward(request, response); return; } } else { //返回的url为loginFormUrl配置的值,如果未配置,跳转到默认登录页面/spring_security_login redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException); } redirectStrategy.sendRedirect(httpRequest, httpResponse, redirectUrl); }
接着分析访问拒绝类异常的处理过程,看AccessDeniedHandlerImpl的handle方法
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { if (!response.isCommitted()) { //如果配置了access-denied-page属性,跳转到指定的url if (errorPage != null) { // Put exception into request scope (perhaps of use to a view) request.setAttribute(SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY, accessDeniedException); // Set the 403 status code. response.setStatus(HttpServletResponse.SC_FORBIDDEN); // forward to error page. RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage); dispatcher.forward(request, response); //如果没有配置,则直接响应403禁止访问的错误信息到浏览器端 } else { response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage()); } } }
通过以上分析,可以大体上认识到ExceptionTranslationFilter主要拦截两类安全异常:认证异常、访问拒绝异常。而且仅仅是捕获FilterSecurityInterceptor、SwitchUserFilter以及自定义拦截器的异常。所以在自定义拦截器时,需要注意在链中的顺序。
在上面分析过程中,有requestCache.saveRequest(request, response);的语句,具体requestCache的用途下篇分析。
发表评论
-
Spring Security3源码分析-电子书下载
2012-07-30 14:34 8552提供电子书下载链接。 -
Spring Security3源码分析-CAS支持
2012-05-13 21:03 25784Spring Security3对CAS的支持主要在这个spr ... -
Spring Security3源码分析-SSL支持
2012-05-10 12:48 11079Sping Security3对于SSL的支持仅仅表现在对需要 ... -
Spring Security3源码分析-认证授权分析
2012-05-09 21:59 6367前面分析了FilterChainProxy执行过程,也对常用的 ... -
Spring Security3源码分析-Filter链排序分析
2012-05-09 14:39 15311通过前面Spring Security提供的各种Filter的 ... -
Spring Security3源码分析-RequestCacheAwareFilter分析
2012-05-09 12:55 4888RequestCacheAwareFilter过滤器对应的类路 ... -
Spring Security3源码分析-SessionManagementFilter分析-下
2012-05-08 21:03 6339很多spring security3资料在 ... -
Spring Security3源码分析-SessionManagementFilter分析-上
2012-05-08 17:26 10925SessionManagementFilter过滤 ... -
Spring Security3源码分析-AnonymousAuthenticationFilter分析
2012-05-08 10:32 5199AnonymousAuthenticationFilter ... -
Spring Security3源码分析-BasicAuthenticationFilter分析
2012-05-08 09:24 9609BasicAuthenticationFilter过滤器对应的 ... -
Spring Security3源码分析-FilterSecurityInterceptor分析
2012-05-07 17:31 15292FilterSecurityInterceptor过滤器对应的 ... -
Spring Security3源码分析-SecurityContextHolderAwareRequestFilter分析
2012-05-07 10:34 6822SecurityContextHolderAwareReque ... -
Spring Security3源码分析-RememberMeAuthenticationFilter分析
2012-05-06 22:33 5953RememberMeAuthenticationFilter过 ... -
Spring Security3源码分析-UsernamePasswordAuthenticationFilter分析
2012-05-06 11:54 24863UsernamePasswordAuthenticationF ... -
Spring Security3源码分析-LogoutFilter分析
2012-05-06 10:18 10306LogoutFilter过滤器对应的类路径为 org.spri ... -
Spring Security3源码分析-SecurityContextPersistenceFilter分析
2012-05-06 08:22 8732通过观察Filter的名字,就能大概猜出来这个过滤器的作用,是 ... -
Spring Security3源码分析-FilterChainProxy执行过程分析
2012-05-06 07:48 4246通过FilterChainProxy的初始化、自定义标签的分析 ... -
Spring Security3源码分析-authentication-manager标签解析
2012-05-05 16:13 21686讲解完http标签的解析过程,authentication-m ... -
Spring Security3源码分析-http标签解析
2012-05-05 15:29 8449在FilterChainProxy初始化的 ... -
Spring Security3源码分析-FilterChainProxy初始化
2012-05-04 16:57 20056很久没有更新博客了,最近对Spring Security做了比 ...
相关推荐
Spring Security-3.0.1 中文官方文档(翻译版) 这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进 行修 正。文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行...
1.1. Spring Security是什么? 1.2. 历史 1.3. 发行版本号 1.4. 获得Spring Security 1.4.1. 项目模块 1.4.1.1. Core - spring-security-core.jar 1.4.1.2. Web - spring-security-web.jar 1.4.1.3. ...
3. Spring Security 4.2的新特性 27 3.1 Web改进 27 3.2配置改进 28 3.3杂项 28 4.样品和指南(从这里开始) 28 5. Java配置 29 5.1 Hello Web安全Java配置 29 5.1.1 AbstractSecurityWebApplicationInitializer 31 ...
1.1. Spring Security是什么? 1.2. 历史 1.3. 发行版本号 1.4. 获得Spring Security 1.4.1. 项目模块 1.4.1.1. Core - spring-security-core.jar 1.4.1.2. Web - spring-security-web.jar 1.4.1.3. Config -...
/**=httpSessionContextIntegrationFilter,basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor class="org.acegisecurity.context....