`
kong0itey
  • 浏览: 298974 次
社区版块
存档分类
最新评论

《Spring Security3》第六章第六部分翻译(Spring Security基于bean的高级配置)

阅读更多

Spring Security 基于bean 的高级配置

 

正如我们在前面几页中看到的那样,基于 bean Spring Security 配置尽管比较复杂,但是提供了一定层次的灵活性,如果复杂应用需要超过 security XML 命名空间风格配置所允许的功能时会用到。

         我们将利用这个章节来阐明可用的一些配置选项以及怎么使用。尽管我们不能提供每个可能属性的细节,但是我们鼓励基于在本章和以前章节学到的内容你开始探索并查询 Javadoc Spring Security 的源码。你仅仅会受限于对这个框架是如何组织起来的知识和你的想象力。

Session 生命周期的调整元素

         Spring Security 有很多地方影响用户的 HttpSession 的生命周期。有很多功能只有将相关类配置成 Spring bean 时才可用。以下的表格列出了能够影响 session 创建和销毁的 bean 属性:

Class (类)

属性

默认值

描述

AbstractAuthentication ProcessingFilter 

UsernamePasswordAuthenticationFilter 的父类)  

allowSessionCreation

true

如果为 true ,当认证失败时创建一个新的 session (存储异常)

UsernamePasswordAuthenticationFilter

allowSessionCreation

true

如果为 true 的话,这个特殊的过滤器将会创建一个 session 存储最后尝试的用户名。

SecurityContextLogoutHandler

invalidateHttpSession

true

如果为 true HttpSession 将会失效(参考 Servlet 规范了解 session 失效的细节)

SecurityContextPersistenceFilter

forceEagerSessionCreation

false

如果为 true ,该过滤器将会在执行链中其它过滤器之前创建一个 session

HttpSessionSecurityContextRepository

allowSessionCreation

true

如果为 true ,如果在请求结束时 session 中还没有 SecurityContext 的话, SecurityContext 将存储到 session 中。

 

         取决于你应用的需要,需要审慎分析用户 session ——包括认证的和非认证的——并调整相应的 session 生命周期。

手动配置其它通用的服务

         还有一些其它的服务,我们已经在 security 命名空间自动配置中使用了。让我们将其添加上,这样就会有一个完整的基本配置实现。

声明缺失的过滤器

         我们将要增强手动配置的过滤器链,添加三个我们还没有配置的服务。包含处理退出、 remember me 以及异常转换。一旦我们完成这些过滤器,我们将会有完整的功能并可以在它启动时深入了解一些有趣的配置选项。

         以下缺失的过滤器将会添加到我们的过滤器链中:

 

Xml代码  收藏代码
  1. < bean   id = "springSecurityFilterChain"    
  2.   class = "org.springframework.security.web.FilterChainProxy" >   
  3.   < security:filter-chain-map   path-type = "ant" >   
  4.     < security:filter-chain   pattern = "/**"   filters ="  
  5.       securityContextPersistenceFilter,  
  6.       logoutFilter,  
  7.       usernamePasswordAuthenticationFilter,  
  8.       rememberMeAuthenticationFilter,  
  9.       anonymousAuthenticationFilter,  
  10.       exceptionTranslationFilter,  
  11.       filterSecurityInterceptor" />   
  12.   </ security:filter-chain-map >   
  13. </ bean >   

 正如在前面做的那样,现在我们需要声明这些 Spring bean 并配置他们以及所有依赖的服务 bean

 

LogoutFilter

         LogoutFilter 的基本配置(它默认用来响应虚拟 URL  /j_spring_security_logout )如下:

 

Xml代码  收藏代码
  1. < bean   id = "logoutFilter"   class ="org.springframework.security   
  2.   .web.authentication.logout.LogoutFilter">   
  3.   <!-- the post-logout destination -->   
  4.   < constructor-arg   value = "/" />   
  5.     < constructor-arg >   
  6.       < array >   
  7.         < ref   local = "logoutHandler" />   
  8.       </ array >   
  9.     </ constructor-arg >   
  10.   < property   name = "filterProcessesUrl"   value = "/logout" />   
  11. </ bean >   

 你会发现构造 LogoutFilter 的方法与其它的认证过滤器都不一样,使用了构造方法而不是 bean 属性。第一个构造参数是用户退出后要转向的 URL ,第二个参数是对 LogoutHandler 实例的引用。

【依赖注入中的构造器哲学。如果你使用 Spring 有一段时间了,可能已经讨论过以适当的面向对象方式管理需要的依赖。尽管 setter 方式对 Spring 的用户来说很便利,但是追求纯正面向对象的人经常会认为如果一个依赖影响到类的功能,那它应该是构造方法签名的一部分(思考一下在 Spring 以前你是怎样写类的)。鉴于 Spring Security 已经发展了有些年头,不同的作者对此有不同的观点,而我们碰巧正好遇到一个或两个这方面的不一致。两种风格的依赖模型都可以——到底使用哪种风格其实取决于你喜欢哪种类型的需求依赖模型。】

         我们还要声明一个简单的 LogoutHandler 的如下:

 

Xml代码  收藏代码
  1. < bean   id = "logoutHandler"   class ="org.springframework.security   
  2.   .web.authentication.logout.SecurityContextLogoutHandler"/>   

 你可能认出这个 LogoutHandler 在我们前几页关于 session 处理的表格中出现过。一个明确配置 logout 处理器的好处就是你能修改用户退出时默认的 session 处理行为。一旦我们完成这两点的配置, Log Out 链接就能够再次开始工作了。

         请记住在第三章 security 命名空间配置中,我们曾经修改应用使用一个不那么明显绑定 Spring Security 的退出 URL 。当我们从 security 命名空间配置方式修改为明确 bean 定义时,这是我们在这个 bean 定义时重写 filterProcessesUrl 属性的原因,以保持应用的配置保持持续性。

RememberMeAuthenticationFilter

         你可能也会回忆起在第三章中使用的 remember me 功能。即使在基于 bean 的配置中,我们也要保持这个有用的 remember me 功能。这关系到一个新的过滤器、新的支持 bean 以及修改一些其它的 bean 。首先让我们看一下这个过滤器:

 

Xml代码  收藏代码
  1. < bean   id = "rememberMeAuthenticationFilter"    
  2.   class ="org.springframework.security.web   
  3.   .authentication.rememberme.RememberMeAuthenticationFilter">   
  4.   < property   name = "rememberMeServices"   ref = "rememberMeServices" />   
  5.   < property   name = "authenticationManager"    ref = "customAuthenticationManager"   />   
  6. </ bean >   

 你会发现对 rememberMeServices 的引用,而它还没有定义。现在让我们定义这个 bean

 

Xml代码  收藏代码
  1. < bean   id = "rememberMeServices"    
  2.   class ="org.springframework.security.web.authentication   
  3.   .rememberme.PersistentTokenBasedRememberMeServices">   
  4.   < property   name = "key"   value = "jbcpPetStore" />   
  5.   < property   name = "tokenValiditySeconds"   value = "3600" />   
  6.   < property   name = "tokenRepository"   ref = "jdbcRememberMeTokenRepository" />   
  7.   < property   name = "userDetailsService"   ref = "jdbcUserService" />   
  8. </ bean >   

 RememberMeServices 实现的很多配置属性与 security 命名空间风格的配置很相似。这两种方法的最大不同是 RememberMeServices 从应用配置的细节中抽象出来了(译者注:即在 security 方式的配置中,已经进行了一些抽象),但是在基于 bean 的配置中, bean 声明必须非常了解在 remember me 功能中所关联的所有 bean 。如果你感到迷惑,请回顾第三章到第四章以了解 remember me 功能所关联的类和流程的细节。

         我们有另一个 bean 应用来织入 remember me token 存储。这个 bean 定义很简单,如下:

 

Xml代码  收藏代码
  1. < bean   id = "jdbcRememberMeTokenRepository"    
  2.   class ="org.springframework.security.web   
  3.   .authentication.rememberme.JdbcTokenRepositoryImpl">   
  4.   < property   name = "dataSource"   ref = "dataSource" />   
  5. </ bean >   

 最后我们需要声明 AuthenticationProvider ,它负责处理 remember me 认证请求。它的声明如下:

 

Xml代码  收藏代码
  1. < bean   id = "rememberMeAuthenticationProvider"    
  2.   class = "org.springframework.security .authentication.RememberMeAuthenticationProvider" >   
  3.   < property   name = "key"   value = "jbcpPetStore" />   
  4. </ bean >   

 你可能会记得这个 key 属性在 AuthenticationProvider (用来进行 token 校验)和 RememberMeServices (用来进行 token 生成)之间共享。要保证它们被设置成相同的。你可能想通过一个 properties 文件来设置这个属性值,那是要 PropertyPlaceholderConfigurer 工具类(或其它类似的)。

         现在我们需要将这个 AuthenticationProvider 织入到 AuthenticationManager 的列表中。

 

Xml代码  收藏代码
  1. < bean   id = "customAuthenticationManager"    
  2.   class = "org.springframework.security .authentication.ProviderManager" >   
  3.   < property   name = "providers" >   
  4.     < list >   
  5.       < ref   local = "daoAuthenticationProvider" />   
  6.       < ref   local =”anonymousAuthenticationProvider” />   
  7.       < ref   local = "rememberMeAuthenticationProvider" />   
  8.     </ list >   
  9.   </ property >   
  10. </ bean >   

 RememberMeServices 必须织入到 UsernamePasswordAuthenticationFilter ,这样 RememberMeServices 就能处理明确的登录成功( remember me cookie 被更新)和失败( remember me 被移除)。(译者注:其实查看源码在登录失败时,没有移除 cookie 的操作)

 

Xml代码  收藏代码
  1. < bean   id = "usernamePasswordAuthenticationFilter"    
  2.   class ="org.springframework.security.web   
  3.   .authentication.UsernamePasswordAuthenticationFilter">   
  4.   < property   name = "authenticationManager"    
  5.   ref = "customAuthenticationManager" />   
  6.   < property   name = "rememberMeServices"   ref = "rememberMeServices" />   
  7. </ bean >   

 最后要记住的一件事(在配置 Spring Security bean 声明时,用户经常遗忘) RememberMeServices 也是 LogoutHandler 功能的一部分,它在用户退出时清理用户的 cookie

 

Xml代码  收藏代码
  1. < bean   id = "logoutFilter"    
  2.   class = "org.springframework.security.web .authentication.logout.LogoutFilter" >   
  3.   < constructor-arg   value = "/" />   
  4.   < constructor-arg >   
  5.     < array >   
  6.       < ref   local = "logoutHandler" />   
  7.       < ref   local = "rememberMeServices" />   
  8.     </ array >   
  9.   </ constructor-arg >   
  10.   < property   name = "filterProcessesUrl"   value = "/logout" />   
  11. </ bean >   

 当这些配置到位,我们就完成了明确织入 remember me 功能。你可能没有想到过 <remember-me> 声明在幕后做了多少的工作。

ExceptionTranslationFilter

         Spring Security 标准的过滤器链中最后一个 servlet 过滤器是 ExceptionTranslationFilter 。从本章我们前面的讨论,回忆一下这个过滤器在认证和授权整个流程中的重要性。最后的这个过滤器需要一个过滤器定义和两个支持 bean

 

Xml代码  收藏代码
  1. < bean   id = "exceptionTranslationFilter"    
  2.   class = "org.springframework.security.web .access.ExceptionTranslationFilter" >   
  3.   < property   name = "authenticationEntryPoint"   ref = "authenticationEntryPoint" />   
  4.   < property   name = "accessDeniedHandler"   ref = "accessDeniedHandler" />   
  5. </ bean >   

 支持 bean 的声明如下:

 

Xml代码  收藏代码
  1. < bean   id = "authenticationEntryPoint"    
  2.   class ="org.springframework.security.web   
  3.   .authentication.LoginUrlAuthenticationEntryPoint">   
  4.   < property   name = "loginFormUrl"   value = "/login.do" />   
  5. </ bean >   
  6. < bean   id = "accessDeniedHandler"    
  7.   class = "org.springframework.security.web .access.AccessDeniedHandlerImpl" >   
  8.   < property   name = "errorPage"   value = "/accessDenied.do" />   
  9. </ bean >   

 你可能会认出 errorPage 指令定义的 Access Denied 页面就是本章前面访问拒绝配置练习中的那个地址。类似的, loginFormUrl 对应于我们在前面看到的 security 命名空间中的 login-page 属性。

明确配置SpEL 表达式和投票器

         让我们看一下与 security 命名空间中 use-expressions="true" 属性等同的 Spring bean 配置:

 

Xml代码  收藏代码
  1. < bean   class ="org.springframework.security   
  2.   .web.access.expression.DefaultWebSecurityExpressionHandler"   
  3.   id = "expressionHandler" />   

 接下来,我们需要建立投票器( Voter )指向表达式处理器,如下:

 

Xml代码  收藏代码
  1. < bean   class ="org.springframework.security.web.access   
  2.   .expression.WebExpressionVoter" id = "expressionVoter" >   
  3.   < property   name = "expressionHandler"   ref = "expressionHandler" />   
  4. </ bean >   

 最后,我们需要使 AccessDecisionManager bean 使用这个投票器。

 

Xml代码  收藏代码
  1. < bean    class = "org.springframework.security.access.vote.AffirmativeBased"    
  2. id = "affirmativeBased" >   
  3.   < property   name = "decisionVoters" >   
  4.     < list >   
  5.       < ref   bean = "expressionVoter" />   
  6.     </ list >   
  7.   </ property >   
  8. </ bean >   

 在完成这些配置以后,我们回到了使用 use-expressions="true" 默认设置的那个点上(译者注:即与使用命名空间配置 use-expressions="true" 一样的效果)。但是,既然我们使用了明确配置方式,那么可以使用自定义的类替换默认的某个或全部类。我们将会本章后面的部分看一个这样的例子。

基于 bean 配置方法安全

         在第五章中,我们使用 security 命名空间 <global-method-security> 声明的方式配置过方法安全。迁移到明确的、基于 bean 的配置时,我们必须配置需要的主要类和支持类以重写 <global-method-security> 声明的功能。

         我们在第五章中,已经开发出完整的以 bean 配置的方法安全,支持各种类型的注解。鉴于这个配置很简单直接,基本上没有什么有意思的属性,所以我们将完整的配置放在附录:参考资料 中以及本章的 dogstore-explicit-base.xml 配置文件里面。

包装明确的配置

         到此时,我们已经完成了配置基于 bean Spring security ,应用也是功能完整的了。如果你想体验 security 命名空间风格的配置与 bean 声明的配置,很容易修改 web.xml 中对 Spring 配置文件的引用从而把一系列配置文件的集合切换到另一个。

l  security 命名空间的配置文件为 web.xml 引用的 dogstore-base.xml dogstore-security.xml

l  基于 bean 的配置文件为 web.xml 引用的 dogstore-explicit-base.xml

从此往后,本书的练习中将会假设你使用的是 security 命名空间配置。如果特定的功能只能使用基于 bean 的配置,我们将会明确说明。我们也会包含一些基于 bean 配置的细节,因为我们知道一些开发人员更愿意拥有这个级别上对安全框架的控制。

我们应该选择什么类型的配置呢?

         希望你的大脑没有从我们刚才的所有配置中变迷糊。你可能会想知道,对于一个典型的工程,应该选择什么类型的配置呢。正如你可能预料的那样,答案是取决于你项目的复杂性以及你重写或自定义 Spring Security 元素的程度。

配置类型

好处

security 命名空间

l  强大、简洁语法,适用于通常的 web 和方法安全配置;

l  用户配置复杂功能时,并不需要知道组件在幕后是如何交互的;

l  security 命名空间进行代码检查和并警告多种潜在的配置缺陷;

l  明显减少缺失配置步骤的可能性。

明确的 bean 定义

l  允许最大灵活性以扩展、重写以及删节标准的 Spring Security 功能;

l  允许自定义过滤器链及根据 URL 模式(使用 <filter-chain> 元素的 pattern 属性)的认证方法。这可能在混合 web service REST 认证以及用户认证时用到;

l  不用直接将配置文件绑定到 Spring Security 命名空间处理上;

l  认证管理器可以明确配置或重写;

l  与更简单的 security 命名空间相比,暴露了有更多的配置选项。

 

         对于大多数项目,比较明智的是以 security 命名空间开始,并在可能的情况下继续使用直到你的应用需要它不满足的功能。要记住的是,自己配置所有需要的 bean bean 间的依赖关系将会明显增加复杂度,在开始之前,你应该对 Spring Security 的结构(可能还包括底层代码)有清晰的理解。

分享到:
评论

相关推荐

    bean配置跑spring security(mysql数据库)_spring security例子

    bean配置跑spring security(mysql数据库)_spring security例子 博客:blog.csdn.net/dsundsun

    SpringSecurity.zip

    它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制...

    Spring Security、Spring Social 、Spring Security OAuth

    它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制...

    spring security 参考手册中文版

    第六部分 其他主题 209 27.域对象安全(ACL) 209 27.1概述 209 27.2重要概念 211 27.3入门 214 28.预认证方案 216 28.1预认证框架类 216 28.1.1 AbstractPreAuthenticatedProcessingFilter 217 J2...

    Spring Security-3.0.1中文官方文档(翻译版)

    Spring Security-3.0.1 中文官方文档(翻译版) 这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进 行修 正。文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行...

    Spring攻略PDF版

     第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章 Spring MVC框架   第11章 整合Spring...

    thymeleaf-extras-springsecurity-3.0-master.zip

    This module provides a new dialect called org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect or org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect (depending on the ...

    Spring攻略中文版PDF

     第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章 Spring MVC框架   第11章 整合Spring...

    SpringSecurity 3.0.1.RELEASE.CHM

    Spring Bean配置 18.4.6. LDAP属性和自定义UserDetails 19. JSP标签库 19.1. 声明Taglib 19.2. authorize标签 19.3. authentication 标签 19.4. accesscontrollist 标签 20. Java认证和授权服务(JAAS)供应...

    Spring攻略英文版(附带源码)

     第6章 Spring 2.x AOP和AspectJ支持  第二部分 基础主题  第7章 Spring对JDBC的支持   第8章 Spring中的事务管理   第9章 Spring对ORM的支持   第10章 Spring MVC框架   第11章 整合Spring与其他...

    SpringSecurity实战教程.txt

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,...

    Spring Security

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,...

    Spring Security详细介绍及使用含完整代码(值得珍藏)

    Spring Security是一个功能强大且高度可定制的安全框架,专为基于Spring的企业应用系统提供声明式的安全访问控制解决方案。该框架充分利用了Spring IoC、DI(依赖注入)和AOP(面向切面编程)等核心功能,通过一组可...

    spring security3配置和使用

    该项目的历史,然后看看如何开始在程序中使用框架。特别是,我们将看看命名控件配置提供了一个更加简单的方式,在使用传统的spring bean配置时,你不得不实现所有类。 我们也会看看可用的范例程序。

    基于Springboot+Mybatis+ SpringMvc+springsecrity+Redis完整网站后台管理系统

    spring security 全注解式的权限管理 动态配置权限,角色和资源,权限控制到按钮粒度 采用token进行权限校验,禁用session,未登录返回401,权限不足返回403 采用redis存储token及权限信息 内置功能: 用户管理...

    Spring Security 中文教程.pdf

    Spring Bean配置 19.4.6. LDAP属性和自定义UserDetails 20. JSP标签库 20.1. 声明Taglib 20.2. authorize 标签 20.3. authentication 标签 20.4. accesscontrollist 标签 21. Java认证和授权服务...

    spring-boot整合security和mybatis-plus代码

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean。

    spring-security-4.2.5.RELEASE-source.zip

    Spring Security 4.2.5是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of ...

    SPRINGSECURITY应用案例

    SPRINGSECURITY 3.2 在WEB应用中的案例源码, 1.如何改造登陆验证 2.如何使用数据库中配置的资源权限信息进行访问控制 3.如何控制对SPRINGBEAN中的类方法的控制

    spring-security-samples-tutorial 源码实例

    Spring Security是一个能够为基于Spring的企业应用系统提供描述性安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(依赖注入,也称控制反转)和AOP(面向切...

Global site tag (gtag.js) - Google Analytics