- 浏览: 1202270 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
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 8625提供电子书下载链接。 -
Spring Security3源码分析-CAS支持
2012-05-13 21:03 25880Spring Security3对CAS的支持主要在这个spr ... -
Spring Security3源码分析-SSL支持
2012-05-10 12:48 11169Sping Security3对于SSL的支持仅仅表现在对需要 ... -
Spring Security3源码分析-认证授权分析
2012-05-09 21:59 6478前面分析了FilterChainProxy执行过程,也对常用的 ... -
Spring Security3源码分析-Filter链排序分析
2012-05-09 14:39 15468通过前面Spring Security提供的各种Filter的 ... -
Spring Security3源码分析-RequestCacheAwareFilter分析
2012-05-09 12:55 5030RequestCacheAwareFilter过滤器对应的类路 ... -
Spring Security3源码分析-SessionManagementFilter分析-下
2012-05-08 21:03 6432很多spring security3资料在 ... -
Spring Security3源码分析-SessionManagementFilter分析-上
2012-05-08 17:26 11036SessionManagementFilter过滤 ... -
Spring Security3源码分析-AnonymousAuthenticationFilter分析
2012-05-08 10:32 5302AnonymousAuthenticationFilter ... -
Spring Security3源码分析-BasicAuthenticationFilter分析
2012-05-08 09:24 9707BasicAuthenticationFilter过滤器对应的 ... -
Spring Security3源码分析-FilterSecurityInterceptor分析
2012-05-07 17:31 15406FilterSecurityInterceptor过滤器对应的 ... -
Spring Security3源码分析-SecurityContextHolderAwareRequestFilter分析
2012-05-07 10:34 6896SecurityContextHolderAwareReque ... -
Spring Security3源码分析-RememberMeAuthenticationFilter分析
2012-05-06 22:33 6043RememberMeAuthenticationFilter过 ... -
Spring Security3源码分析-UsernamePasswordAuthenticationFilter分析
2012-05-06 11:54 24962UsernamePasswordAuthenticationF ... -
Spring Security3源码分析-LogoutFilter分析
2012-05-06 10:18 10473LogoutFilter过滤器对应的类路径为 org.spri ... -
Spring Security3源码分析-SecurityContextPersistenceFilter分析
2012-05-06 08:22 8875通过观察Filter的名字,就能大概猜出来这个过滤器的作用,是 ... -
Spring Security3源码分析-FilterChainProxy执行过程分析
2012-05-06 07:48 4324通过FilterChainProxy的初始化、自定义标签的分析 ... -
Spring Security3源码分析-authentication-manager标签解析
2012-05-05 16:13 21778讲解完http标签的解析过程,authentication-m ... -
Spring Security3源码分析-http标签解析
2012-05-05 15:29 8616在FilterChainProxy初始化的 ... -
Spring Security3源码分析-FilterChainProxy初始化
2012-05-04 16:57 20158很久没有更新博客了,最近对Spring Security做了比 ...
相关推荐
综上,Spring Security 3.1.3源码的分析和学习,可以帮助开发者深入理解Web安全原理,掌握如何利用这个强大的框架来保护应用程序免受攻击。通过对源码的研究,可以更清晰地了解其内部工作方式,从而更好地进行定制化...
SpringBoot_SpringSecurity-源码.zip 这个压缩包文件主要包含了SpringBoot集成SpringSecurity的源码分析。SpringBoot是Java开发中一个流行的轻量级框架,它简化了配置和应用部署,使得开发者可以快速搭建应用程序。...
3. **Filter安全链**:Spring Security 的Web安全功能主要通过一系列过滤器实现,这些过滤器构成了安全链。其中关键的过滤器有`DelegatingFilterProxy`、`ChannelProcessingFilter`、`...
### Spring Security 源码分析知识...以上内容涵盖了 Spring Security 3 的源码分析中几个关键点的具体内容。通过对这些内容的深入学习和理解,可以更好地掌握 Spring Security 的工作原理及其在实际项目中的应用技巧。
在分析`spring-security 5.0`的源码时,我们可以深入理解其核心机制,帮助我们更好地使用和扩展该框架。 1. **模块结构**: Spring Security 5.0 的源码包含多个模块,如`core`、`config`、`web`等。`core`模块...
通过这些源码分析,我们可以了解到Spring Security是如何在背后工作,保护应用程序免受未经授权的访问。理解这些组件的工作原理对于定制和优化安全配置至关重要,同时也有助于开发者解决潜在的安全问题。
7. **源码分析**:源码包允许开发者深入研究Spring Security的实现细节,了解其内部的工作流程,这对于自定义扩展和调试是非常有价值的。例如,可以通过阅读`AuthenticationManager`和`UserDetailsService`的实现来...
6. **源码分析**: Spring Security的源码是开源的,你可以深入研究其内部工作原理,了解每个组件是如何协同工作的。这将帮助你更好地理解和定制这个框架。 7. **工具**: - Spring Security的官方文档和教程是...
源码分析对于深入理解Spring Security的工作原理至关重要。通过阅读源码,开发者可以了解每个组件如何协同工作,以及如何根据特定需求定制框架。例如,你可以研究`FilterSecurityInterceptor`如何调用`...
6. **源码分析**: 分析`ValidateCodeAuthenticationFilter`的源码可以帮助我们理解验证码验证的整个流程,包括何时生成验证码、如何将其与用户的会话关联、以及如何在认证过程中验证它。这有助于我们定制自己的...
通过学习和分析这些源代码,你可以深入了解Spring Security的工作原理,以及如何将其集成到你的应用程序中以实现安全控制。对于开发人员来说,理解这些核心概念和组件非常重要,因为它们构成了Spring Security强大...
Acegi是Spring Security的前身,它是一个用于Java平台的安全框架,专为Spring应用程序设计。本教程将引导初学者逐步了解如何在实际项目中应用Acegi安全框架,以便为你的Web应用提供强大的身份验证和授权功能。 首先...
Acegi Security是Spring框架早期的一个安全模块,它提供了全面的认证和授权功能,为Java企业级应用提供了强大的安全控制。本文将重点解析Acegi Security中的各个过滤器,这些过滤器在保护应用程序的安全方面起着至关...