`

Security命名空间配置

阅读更多

Chapter 2. Security命名空间配置

Security命名空间配置

2.1. 介绍

从Spring-2.0开始可以使用命名空间的配置方式。 使用它呢,可以通过附加xml架构,为传统的spring beans应用环境语法做补充。 你可以在spring参考文档得到更多信息。 命名空间元素可以简单的配置单个bean,或使用更强大的,定义一个备用配置语法,这可以更加紧密的匹配问题域,隐藏用户背后的复杂性。 简单元素可能隐藏事实,多种bean和处理步骤添加到应用环境中。 比如,把下面的security命名元素添加到应用环境中,将会为测试用途,在应用内部启动一个内嵌LDAP服务器:

  <security:ldap-server />

这比配置一个Apache目录服务器bean要简单得多。 最常见的替代配置需求都可以使用ldap-server元素的属性进行配置,这样用户就不用担心他们需要设置什么,不用担心bean里的各种属性。 [1]。使用一个良好的XML编辑器来编辑应用环境文件,应该提供可用的属性和元素信息。 我们推荐你尝试一下 SpringSource工具套件 因为它具有处理spring组合命名空间的特殊功能。

要开始在你的应用环境里使用security命名空间,你所需要的就是把架构声明添加到你的应用环境文件里:

  
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    ...
</beans>
  

在许多例子里,你会看到(在示例中)应用,我们通常使用"security"作为默认的命名空间,而不是"beans",这意味着我们可以省略所有security命名空间元素的前缀,使上下文更容易阅读。 如果你把应用上下文分割成单独的文件,让你的安全配置都放到其中一个文件里,这样更容易使用这种配置方法。 你的安全应用上下文应该像这样开头

<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    ...
</beans:beans>

就在这一章里,我们都将假设使用这种语法。

2.1.1. 命名空间的设计

命名空间被用来设计成,处理框架内最常见的功能,提供一个简化和简洁的语法,使他们在一个应用程序里。 这种设计是基于框架内的大型依赖,可以分割成下面这些部分:

  • Web/HTTP安全 - 最复杂的部分。设置过滤器和相关的服务bean来应用框架验证机制, 保护URL,渲染登录和错误页面还有更多。

  • 业务类(方法)安全 - 可选的安全服务层。

  • AuthenticationManager - 通过框架的其它部分,处理认证请求。

  • AccessDecisionManager - 提供访问的决定,适用于web以及方法的安全。一个默认的主体会被注册,但是你也可以选择自定义一个,使用正常的spring bean语法进行声明。

  • AuthenticationProviders - 验证管理器验证用户的机制。 该命名空间提供几种标准选项,意味着使用传统语法添加自定义bean。

  • UserDetailsService - 密切相关的认证供应器,但往往也需要由其他bean需要。

 

下一章中,我们将看到如何把这些放到一起工作。

2.2. 开始使用安全命名空间配置

在本节中,我们来看看如何使用一些框架里的主要配置,建立一个命名空间配置。 我们假设你最初想要尽快的启动运行,为已有的web应用添加认证支持和权限控制,使用一些测试登录。 然后我们看一下如何修改一下,使用数据库或其他安全信息参数。 在以后的章节里我们将引入更多高级的命名空间配置选项。

2.2.1. 配置web.xml

我们要做的第一件事是把下面的filter声明添加到 web.xml 文件中:

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
      

这是为Spring Security的web机制提供了一个调用钩子。 DelegatingFilterProxy是一个Spring Framework的类,它可以代理一个application context中定义的Spring bean所实现的filter。 这种情况下,bean的名字是"springSecurityFilterChain",这是由命名空间创建的用于处理web安全的一个内部的机制。 注意,你不应该自己使用这个bean的名字。 一旦你把这个添加到你的web.xml中,你就准备好开始编辑呢的application context文件了。 web安全服务是使用<http>元素配置的。

2.2.2. 最小 <http>配置

只需要进行如下配置就可以实现安全配置:

  <http auto-config='true'>
    <intercept-url pattern="/**" access="ROLE_USER" />
  </http>
  

这表示,我们要保护应用程序中的所有URL,只有拥有 ROLE_USER角色的用户才能访问。<http>元素是 所有web相关的命名空间功能的上级元素。<intercept-url>元素定义了 pattern,用来匹配进入的请求URL,使用一个ant路径语法。 access属性定义了请求匹配了指定模式时的需求。使用默认的配置, 这个一般是一个逗号分隔的角色队列,一个用户中的一个必须被允许访问请求。 前缀“ROLE_”表示的是一个用户应该拥有的权限比对。换句话说, 一个普通的基于角色的约束应该被使用。Spring Security中的访问控制不限于简单角色的应用 (因此,我们使用不同的前缀来区分不同的安全属性).我们会在后面看到这些解释是可变的 [2]

Note

你可以使用多个<intercept-url>元素为不同URL的集合定义不同的访问需求, 它们会被归入一个有序队列中,每次取出最先匹配的一个元素使用。 所以你必须把期望使用的匹配条件放到最上边。你也可以添加一个method属性 来限制匹配一个特定的HTTP method(GET, POST, PUT 等等)。对于一个模式同时定义在定义了method和未定义method的情况, 指定method的匹配会无视顺序优先被使用。

要是想添加一些用户,你可以直接使用下面的命名空间直接定义一些测试数据:

  <authentication-manager>
    <authentication-provider>
      <user-service>
        <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
        <user name="bob" password="bobspassword" authorities="ROLE_USER" />
      </user-service>
    </authentication-provider>
  </authentication-manager>
  
        

 

上面的配置定义了两个用户,他们在应用程序中的密码和角色(用在权限控制上)。 也可以从一个标准properties文件中读取这些信息,使用user-serviceproperties属性。 参考in-memory authentication获得更多信息。 使用<authentication-provider>元素意味着用户信息将被认证管理用作处理认证请求。 你可以拥有多个<authentication-provider>元素来定义不同的认证数据, 每个会被需要时使用。

现在,你可以启动程序,然后就会进入登录流程了。 试试这个,或者试试工程里的“tutorial”例子。 上述配置实际上把很多服务添加到了程序里,因为我们使用了auto-config属性。 比如,表单登录和"remember-me"服务自动启动了。

2.2.2.1. auto-config包含了什么?

我们在上面用到的auto-config属性,其实是下面这些配置的缩写:

  <http>
    <form-login />
    <http-basic />
    <logout />
  </http>
  
          

这些元素分别与form-login,基本认证和注销处理对应。 [3] 他们拥有各自的属性,来改变他们的具体行为。

2.2.2.2. 表单和基本登录选项

你也许想知道,在需要登录的时候,去哪里找这个登录页面,到现在为止我们都没有提到任何的HTML或JSP文件。 实际上,如果我们没有确切的指定一个页面用来登录,Spring Security会自动生成一个,基于可用的功能,为这个URL使用标准的数据,处理提交的登录,然后在登陆后发送到默认的目标URL。 然而,命名空间提供了许多支持,让你可以自定义这些选项。 比如,如果你想实现自己的登录页面,你可以使用:

  <http auto-config='true'>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/**" access="ROLE_USER" />
    <form-login login-page='/login.jsp'/>
  </http>
  
        

注意,你依旧可以使用auto-config。 这个form-login元素会覆盖默认的设置。 也要注意我们需要添加额外的intercept-url元素,指定用来做登录的页面的URL, 这些URL应该可以被匿名访问。[4] 否则,这些请求会被/**部分拦截,它没法访问到登录页面。 这是一个很常见的配置错误,它会导致系统出现无限循环。 Spring Security会在日志中发出一个警告,如果你的登录页面是被保护的。 也可能让所有的请求都匹配特定的模式,通过完全的安全过滤器链:

  <http auto-config='true'>
    <intercept-url pattern="/css/**" filters="none"/>
    <intercept-url pattern="/login.jsp*" filters="none"/>
    <intercept-url pattern="/**" access="ROLE_USER" />
    <form-login login-page='/login.jsp'/>
  </http>
  
          

主要的是意识到这些请求会被完全忽略,对任何Spring Security 中web相关的配置,或额外的属性,比如requires-channel, 所以你会不能访问当前用户信息,或调用被保护方法,在请求过程中。 使用access='IS_AUTHENTICATED_ANONYMOUSLY'作为一个选择方式 如果你还想要安全过滤器链起作用。

如果你希望使用基本认证,代替表单登录,可以把配置改为:

  <http auto-config='true'>
    <intercept-url pattern="/**" access="ROLE_USER" />
    <http-basic />
  </http>
  
        

基本身份认证会被优先用到,在用户尝试访问一个受保护的资源时,用来提示用户登录。 在这种配置中,表单登录依然是可用的,如果你还想用的话,比如,把一个登录表单内嵌到其他页面里。

2.2.2.2.1. 设置一个默认的提交登陆目标

如果在进行表单登陆之前,没有试图去访问一个被保护的资源,default-target-url就会起作用。 这是用户登陆后会跳转到的URL,默认是"/"。 你也可以把always-use-default-target属性配置成"true",这样用户就会一直跳转到这一页(无论登陆是“跳转过来的”还是用户特定进行登陆)。 如果你的系统一直需要用户从首页进入,就可以使用它了,比如:

  <http>
    <intercept-url pattern='/login.htm*' filters='none'/>
    <intercept-url pattern='/**' access='ROLE_USER' />
    <form-login login-page='/login.htm' default-target-url='/home.htm'
        always-use-default-target='true' />
  </http>
  
            

 

2.2.3. 使用其他认证提供器

现实中,你会需要更大型的用户信息源,而不是写在application context里的几个名字。 多数情况下,你会想把用户信息保存到数据库或者是LDAP服务器里。 LDAP命名空间会在LDAP章里详细讨论,所以我们这里不会讲它。 如果你自定义了一个Spring Security的UserDetailsService实现,在你的application context中名叫"myUserDetailsService",然后你可以使用下面的验证。

  <authentication-manager>
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>
  
        

如果你想用数据库,可以使用下面的方式

  <authentication-manager>
    <authentication-provider>
      <jdbc-user-service data-source-ref="securityDataSource"/>
    </authentication-provider>
  </authentication-manager>
  
        

这里的“securityDataSource”就是 DataSource bean在application context里的名字,它指向了包含着Spring Security用户信息的表。 另外,你可以配置一个Spring Security JdbcDaoImpl bean,使用user-service-ref属性指定:

  <authentication-manager>
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>

  <beans:bean id="myUserDetailsService"
        class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <beans:property name="dataSource" ref="dataSource"/>
  </beans:bean>
  
        

你也可以使用标准的AuthenticationProvider类,像下面

  <authentication-manager>
    <authentication-provider ref='myAuthenticationProvider'/>
  </authentication-manager>
  
        

这里myAuthenticationProvider是你的application context 中的一个bean的名字,它实现了AuthenticationProvider。 查看Section 2.6, “验证管理器和命名空间”了解更多信息, AuthenticationManager使用命名空间在Spring Security 中是如何配置的。

2.2.3.1. 添加一个密码编码器

你的密码数据通常要使用一种散列算法进行编码。 使用<password-encoder>元素支持这个功能。 使用SHA加密密码,原始的认证供应器配置,看起来就像这样:

<authentication-manager>
  <authentication-provider>
    <password-encoder hash="sha"/>
    <user-service>
      <user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"
            authorities="ROLE_USER, ROLE_ADMIN" />
      <user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f"
            authorities="ROLE_USER" />
    </user-service>
  </authentication-provider>
</authentication-manager>
  
          

 

在使用散列密码时,用盐值防止字典攻击是个好主意,Spring Security也支持这个功能。 理想情况下,你可能想为每个用户随机生成一个盐值,不过,你可以使用从UserDetailsService读取出来的UserDetails对象中的属性。 比如,使用username属性,你可以这样用:

  <password-encoder hash="sha">
    <salt-source user-property="username"/>
  </password-encoder>
    

你可以通过password-encoderref属性,指定一个自定义的密码编码器bean。 这应该包含application context中一个bean的名字,它应该是Spring Security的PasswordEncoder接口的一个实例。

2.3. 高级web特性

2.3.1. Remember-Me认证

参考Remember-Me章获得remember-me命名空间配置的详细信息。

2.3.2. 添加HTTP/HTTPS信道安全

如果你的同时支持HTTP和HTTPS协议,然后你要求特定的URL只能使用HTTPS,这时可以直接使用<intercept-url>requires-channel属性:

  <http>
    <intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
    <intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>
    ...
  </http>
        

使用了这个配置以后,如果用户通过HTTP尝试访问"/secure/**"匹配的网址,他们会先被重定向到HTTPS网址下。 可用的选项有"http", "https" 或 "any"。 使用"any"意味着使用HTTP或HTTPS都可以。

如果你的程序使用的不是HTTP或HTTPS的标准端口,你可以用下面的方式指定端口对应关系:

  <http>
    ...
    <port-mappings>
      <port-mapping http="9080" https="9443"/>
    </port-mappings>
  </http>
        

你可以在???找到更详细的讨论。

2.3.3. 会话管理

2.3.3.1. 检测超时

你可以配置Spring Security检测失效的session ID, 并把用户转发到对应的URL。这可以通过 session-management元素配置: <http> ... <session-management invalid-session-url="/sessionTimeout.htm" /> </http>

2.3.3.2. 同步会话控制

如果你希望限制单个用户只能登录到你的程序一次,Spring Security通过添加下面简单的部分支持这个功能。 首先,你需要把下面的监听器添加到你的web.xml文件里,让Spring Security获得session生存周期事件: <listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener> 然后,在你的application context加入如下部分:

  <http>
    ...
    <session-management>
        <concurrency-control max-sessions="1" />
    </session-management>
  </http>
        

这将防止一个用户重复登录好几次-第二次登录会让第一次登录失效。 通常我们更想防止第二次登录,这时候我们可以使用

  <http>
    ...
    <session-management>
        <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
    </session-management>
  </http>
        

第二次登录将被阻止,通过“注入”,我们的意思是用户会被转发到 authentication-failure-url,如果使用了form-based登录。 如果第二次验证使用了其他非内置的机制,比如“remember-me”, 一个“未认证”(402)错误就会发送给客户端。 如果你希望使用一个错误页面替代,你可以在session-management 中添加 session-authentication-error-url属性。

如果你为form-based登录使用了自定义认证, 你就必须特别配置同步会话控制。更多的细节可以在 会话管理章节找到。

 

2.3.3.3. 防止Session固定攻击

Session固定攻击是一个潜在危险,当一个恶意攻击者可以创建一个session访问一个网站的时候,然后说服另一个用户登录到同一个会话上(比如,发送给他们一个包含了session标识参数的链接)。 Spring Security通过在用户登录时,创建一个新session来防止这个问题。 如果你不需要保护,或者它与其他一些需求冲突,你可以通过使用<http>中的session-fixation-protection属性来配置它的行为,它有三个选项

  • migrateSession - 创建一个新session,把原来session中所有属性复制到新session中。这是默认值。

  • none - 什么也不做,继续使用原来的session。

  • newSession - 创建一个新的“干净的”session,不会复制session中的数据。

 

2.3.4. 对OpenID的支持

命名空间支持OpenID登录,替代普通的表单登录,或作为一种附加功能,只需要进行简单的修改:

  <http>
    <intercept-url pattern="/**" access="ROLE_USER" />
    <openid-login />
  </http>
  

你应该注册一个OpenID供应器(比如myopenid.com),然后把用户信息添加到你的内存<user-service>中:

  <user name="http://jimi.hendrix.myopenid.com/" authorities="ROLE_USER" />
  

你应该可以使用myopenid.com网站登录来进行验证了。 也可能选择一个特定的UserDetailsService bean 来使用OpenID,通过设置元素。 查看上一节认证提供器获得更多信息。 请注意,上面用户配置中我们省略了密码属性,因为这里的用户数据只用来为数据读取数据。 内部会生成一个随机密码,放置我们使用用户数据时出现问题, 无论在你的配置的地方使用认证信息。

2.3.4.1. 属性交换

支持OpenID的 属性交换。 作为一个例子,下面的配置会尝试从OpenID提供器中获得email和全名, 这些会被应用程序使用到:

  <openid-login>
    <attribute-exchange>
      <openid-attribute name="email" type="http://axschema.org/contact/email" required="true" />
      <openid-attribute name="name" type="http://axschema.org/namePerson" />
    </attribute-exchange>
  </openid-login>
            

每个OpenID的“type”属性是一个URI,这是由特定的schema决定的, 在这个例子中是http://axschema.org/。 如果一个属性必须为了成功认证而获取,可以设置required。 确切的schema和对属性的支持会依赖于你使用的OpenID提供器。属性值作为认证过程的一部分返回, 可以使用下面的代码在后面的过程中获得:

OpenIDAuthenticationToken token = (OpenIDAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
List<OpenIDAttribute> attributes = token.getAttributes();
            

OpenIDAttribute包含的属性类型和获取的值 (或者在多属性情况下是多个值)。我们将看到更多关于 SecurityContextHolder如何使用的信息, 只要我们在技术概述章节浏览核心Spring Security组件。

2.3.5. 添加你自己的filter

如果你以前使用过Spring Security,你就应该知道这个框架里维护了一个过滤器链,来提供服务。 你也许想把你自己的过滤器添加到链条的特定位置,或者使用一个Spring Security的过滤器,这个过滤器现在还没有在命名空间配置中进行支持(比如CAS)。 或者你想要使用一个特定版本的标准命名空间过滤器,比如<form-login>创建的UsernamePasswordAuthenticationFilter,从而获得一些额外的配置选项的优势,这些可以通过直接配置bean获得。 你如何在命名空间配置里实现这些功能呢?过滤器链现在已经不能直接看到了。

过滤器顺序在使用命名空间的时候是被严格执行的。 当application context创建时,过滤器bean通过namespace的处理代码进行排序, 标准的spring security过滤器都有自己的假名和一个容易记忆的位置。

Note

在之前的版本中,排序是在过滤器实例创建后执行的,在application context 的执行后的过程中。在3.0+版本中,执行会在bean元元素级别被执行,在bean实例化之前。 这会影响到你如何添加自己的过滤器,实体过滤器列表 必须在解析<http>元素的过程中了解这些, 所以3.0中的语法变化的很明显。

有关创建过滤器的过滤器,假名和命名空间元素,属性可以在Table 2.1, “标准过滤器假名和顺序”中找到。 过滤器按照次序排列在过滤器链中。

Table 2.1. 标准过滤器假名和顺序

假名 过滤器累 命名空间元素或属性
CHANNEL_FILTER ChannelProcessingFilter http/intercept-url@requires-channel
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter session-management/concurrency-control
SECURITY_CONTEXT_FILTER SecurityContextPersistenceFilter http
LOGOUT_FILTER LogoutFilter http/logout
X509_FILTER X509AuthenticationFilter http/x509
PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter Subclasses N/A
CAS_FILTER CasAuthenticationFilter N/A
FORM_LOGIN_FILTER UsernamePasswordAuthenticationFilter http/form-login
BASIC_AUTH_FILTER BasicAuthenticationFilter http/http-basic
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareFilter http/@servlet-api-provision
REMEMBER_ME_FILTER RememberMeAuthenticationFilter http/remember-me
ANONYMOUS_FILTER SessionManagementFilter http/anonymous
SESSION_MANAGEMENT_FILTER AnonymousAuthenticationFilter session-management
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter http
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor http
SWITCH_USER_FILTER SwitchUserAuthenticationFilter N/A


你可以把你自己的过滤器添加到队列中,使用custom-filter元素,使用这些名字中的一个,来指定你的过滤器应该出现的位置:

  <http>
     <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
  </http>

  <beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>
  

你还可以使用afterbefore属性,如果你想把你的过滤器添加到队列中另一个过滤器的前面或后面。 可以分别在position属性使用"FIRST" 或 "LAST"来指定你想让你的过滤器出现在队列元素的前面或后面。

避免过滤器位置发生冲突

如果你插入了一个自定义的过滤器,而这个过滤器可能与命名空间自己创建的标准过滤器放在同一个位置上,这样首要的是你不要错误包含命名空间的版本信息。 避免使用auto-config属性,然后删除所有会创建你希望替换的过滤器的元素。

注意,你不能替换那些<http>元素自己使用而创建出的过滤器,比如SecurityContextPersistenceFilter, ExceptionTranslationFilterFilterSecurityInterceptor

如果你替换了一个命名空间的过滤器,而这个过滤器需要一个验证入口点(比如,认证过程是通过一个未通过验证的用户访问受保护资源的尝试来触发的),你将也需要添加一个自定义的入口点bean。

2.3.5.1. 设置自定义 AuthenticationEntryPoint

如果你没有通过命名空间,使用表单登陆,OpenID或基本认证,你可能想定义一个认证过滤器,并使用传统bean语法定义一个入口点然后把它链接到命名空间里,就像我们已经看到的那样。 对应的AuthenticationEntryPoint可以使用<http>元素中的entry-point-ref属性来进行设置。

CAS示例程序是一个在命名空间中使用自定义bean的好例子,包含这种语法。 如果你对认证入口点并不熟悉,可以在技术纵览章中找到关于它们的讨论。

2.4. 保护方法

从版本2.0开始Spring Security大幅改善了对你的服务层方法添加安全。 它提供对JSR-250安全注解的支持,这与框架提供的@secured注解相似。 从3.0开始,你也可以使用新的基于表达式的注解。 你可以提供安全给单个bean,使用intercept-methods来装饰bean的声明, 或者你可以控制多个bean,通过实体服务层,使用AspectJ演示的切点功能。

2.4.1. <global-method-security>元素

这个元素用来在你的应用程序中启用基于安全的注解(通过在这个元素中设置响应的属性),也可以用来声明将要应用在你的实体application context中的安全切点组。 你应该只定义一个<global-method-security>元素。 下面的声明同时启用Spring Security的@Secured和JSR-250注解:

  <global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
  

向一个方法(或一个类或一个接口)添加注解,会限制对这个方法的访问。 Spring Security原生注解支持为方法定义一系列属性。 这些属性将传递给AccessDecisionManager,进行决策:

  public interface BankService {

    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public Account readAccount(Long id);

    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public Account[] findAccounts();

    @Secured("ROLE_TELLER")
    public Account post(Account account, double amount);
  }

 

为了使用新的基于表达式的预付,你可以好似用

  <global-method-security pre-post-annotations="enabled" />
      

对应的代码将会是这样

   public interface BankService {

     @PreAuthorize("isAnonymous()")
     public Account readAccount(Long id);

     @PreAuthorize("isAnonymous()")
     public Account[] findAccounts();

     @PreAuthorize("hasAuthority('ROLE_TELLER')")
     public Account post(Account account, double amount);
   }
        

2.4.1.1. 使用protect-pointcut添加安全切点

protect-pointcut是非常强大的,它让你可以用简单的声明对多个bean的进行安全声明。 参考下面的例子:

  <global-method-security>
    <protect-pointcut expression="execution(* com.mycompany.*Service.*(..))"
        access="ROLE_USER"/>
  </global-method-security>

          

这样会保护application context中的符合条件的bean的所有方法,这些bean要在com.mycompany包下,类名以"Service"结尾。 ROLE_USER的角色才能调用这些方法。 就像URL匹配一样,指定的匹配要放在切点队列的最前面,第一个匹配的表达式才会被用到。

2.5. 默认的AccessDecisionManager

这章假设你有一些Spring Security权限控制有关的架构知识。 如果没有,你可以跳过这段,以后再来看,因为这章只是为了自定义的用户设置的,需要在简单基于角色安全的基础上加一些客户化的东西。

当你使用命名空间配置时,默认的AccessDecisionManager实例会自动注册,然后用来为方法调用和web URL访问做验证,这些都是基于你设置的intercept-urlprotect-pointcut权限属性内容(和注解中的内容,如果你使用注解控制方法的权限)。

默认的策略是使用一个AffirmativeBased AccessDecisionManager ,以及RoleVoterAuthenticatedVoter。 可以在authorization中获得更多信息。

2.5.1. 自定义AccessDecisionManager

如果你需要使用一个更复杂的访问控制策略,把它设置给方法和web安全是很简单的。

对于方法安全,你可以设置global-security里的access-decision-manager-ref属性,用对应 AccessDecisionManager bean在application context里的id:

  <global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
    ...
  </global-method-security>
  

 

web安全安全的语法也是一样,但是放在http元素里:

  <http access-decision-manager-ref="myAccessDecisionManagerBean">
    ...
  </http>
  

 

2.6. 验证管理器和命名空间

主要接口提供了验证服务在Spring Security中, 是AuthenticationManager。 通常是Spring Security中ProviderManager类的一个实例, 如果你以前使用过框架,你可能已经很熟悉了。 如果没有,它会在稍后被提及,在#tech-intro-authentication。 bean实例被使用authentication-manager命名空间元素注册。 你不能好似用一个自定义的AuthenticationManager 如果你使用HTTp或方法安全,在命名空间中,但是它不应该是一个问题, 因为你完全控制了使用的AuthenticationProvider

你可能注册额外的AuthenticationProviderbean, 在ProviderManager中,你可以使用 <authentication-provider>做这些事情,使用ref属性, 这个属性的值,是你希望添加的provider的bean的名字,比如:

  <authentication-manager>
    <authentication-provider ref="casAuthenticationProvider"/>
  </authentication-manager>
  <bean id="casAuthenticationProvider"
      class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <security:custom-authentication-provider />
    ...
  </bean>
  

另一个常见的需求是,上下文中的另一个bean可能需要引用AuthenticationManager。 你可以为AuthenticationManager注册一个别名,然后在application context的其他地方使用这个名字。

  <security:authentication-manager alias="authenticationManager">
     ...
  </security:authentication-manager>

  <bean id="customizedFormLoginFilter"
        class="com.somecompany.security.web.CustomFormLoginFilter">
     <property name="authenticationManager" ref="authenticationManager"/>
     ...
  </bean>
  

 



[1] 你可以在LDAP的章节里,找到更多有关使用的ldap-server的元素。

[2] access中逗号分隔的值的解释依赖使用的 AccessDecisionManager的实现。 在Spring Security 3.0中,这个属性也可以使用EL表达式

[3] 在3.0之前按,这里列表中还包含remember-me功能。 这是因为一些配置上容易冲突的问题所以在3.0中被移除了。 在3.0中,AnonymousAuthenticationFilter已经成为了默认的 <http>配置的一部分,所以<anonymous /> 元素无论是否设置auto-config都会被添加到配置中。

[4] 参考匿名认证章节 和AuthenticatedVoter类 获得更多细节,和IS_AUTHENTICATED_ANONYMOUSLY如何被处理。

分享到:
评论

相关推荐

    spring security 2.0 命名空间配置(带例子)

    在这个主题中,我们将深入探讨Spring Security 2.0的命名空间配置,并通过实例来理解其工作原理。 在Spring Security 2.0中,命名空间配置是简化安全配置的一种方式。它允许开发者使用XML配置文件中的特定命名空间...

    SpringSecurity笔记2-SpringSecurity命名空间

    SpringSecurity是Java领域中一款...总的来说,掌握SpringSecurity的命名空间配置对于构建安全的Java Web应用至关重要。通过合理使用这些命名空间,开发者可以高效地实现复杂的安全策略,同时保持代码的整洁和可维护性。

    spring security3 中文版本

    #### 二、Spring Security 命名空间配置 ##### 2.1 命名空间的设计 Spring Security 提供了一个简洁的命名空间,用于简化配置过程。这种设计使得开发者可以使用更少的 XML 配置来实现复杂的安全需求。 ##### 2.2 ...

    spring-security 官方文档 中文版

    **2.1 Security 命名空间配置** - **命名空间的设计**:Spring Security 提供了一个专用的 XML 命名空间来简化安全性配置。 - **开始使用安全命名空间配置**: - **配置 web.xml**:需要在 web.xml 中配置 Spring ...

    Spring_Security_官方文档

    #### Security命名空间配置 Spring Security通过XML命名空间简化了安全相关的配置。这部分文档详细介绍了如何使用安全命名空间配置来实现Web应用的安全性,包括如何配置HTTP安全、如何定义访问决策管理器、如何设置...

    springsecurity2x.pdf

    2. **Security命名空间配置** - **命名空间设计** 为了简化配置,Spring Security引入了安全命名空间(Security Namespace),它提供了一种声明式的方式来配置安全设置。 - **开始使用命名空间配置** 开发者首先...

    Spring Security 中文教程.pdf

    #### 二、Security命名空间配置 - **命名空间设计**:Spring Security引入了专用的XML命名空间来简化配置,使得配置变得更加直观和简洁。 - **开始使用安全命名空间配置**:通过简单的XML配置即可完成大部分安全性...

    spring-security-reference.pdf

    探讨了Spring Security的XML命名空间配置方式,这是较早之前的配置方式,尽管在新版本中推荐使用Java配置。 - **开始使用** 配置中包含如何在`web.xml`中集成Spring Security,以及如何设置一个基本的`&lt;http&gt;`...

    Spring Security 3.0.1中文官方文档

    接着,文档介绍了Security命名空间配置,这是一种使用XML来配置Spring Security的方式。这部分内容包括了web.xml的配置、最小http配置以及一些高级web特性,比如Remember-Me认证、HTTPS信道安全、会话管理以及如何...

    Spring_Security-3.0.1中文官方文档

    **二、Security命名空间配置** **2.1 安全命名空间的设计** Spring Security引入了安全命名空间,使得配置更加简洁、直观。这包括了如何配置HTTP安全、方法级别的安全以及自定义过滤器等。 **2.2 开始使用安全命名...

    Spring_Security-3.0.1_官方文档

    #### 二、Security 命名空间配置 ##### 2.1 命名空间的设计 Spring Security 提供了一个专门的命名空间来简化安全配置的编写。这种配置方式不仅减少了 XML 配置文件的复杂度,还能使配置更加直观和易于理解。 ###...

    Spring_Security-3.0.1_中文自学教程.pdf

    #### 二、Security 命名空间配置 ##### 2.1 命名空间的设计 Spring Security 引入了一个新的 XML 命名空间来简化安全配置的过程。这使得配置变得更加直观和简单。 ##### 2.2 开始使用安全命名空间配置 - **配置 ...

    Spring Security 2.0.x完全中文参考文档

    Security命名空间配置 **2.1. 介绍** 为了简化Spring Security的配置,该框架提供了特定的安全命名空间,使得开发人员可以更加容易地进行配置。 **2.1.1. 命名空间的设计** Spring Security 的安全命名空间设计...

    Spring Security 3.0.1 pdf 中文参考文档

    Security 命名空间配置** - **目的:** 使用 Spring Security 的命名空间简化安全相关的配置。 - **设计:** 命名空间的设计是为了让配置更加直观且易于理解。 - **配置 web.xml:** - 需要在 web.xml 中配置 ...

    SpringSecurity 3.0.1.RELEASE.CHM

    2. Security命名空间配置 2.1. 介绍 2.1.1. 命名空间的设计 2.2. 开始使用安全命名空间配置 2.2.1. 配置web.xml 2.2.2. 最小 配置 2.2.2.1. auto-config包含了什么? 2.2.2.2. 表单和基本登录选项 2.2.3. ...

Global site tag (gtag.js) - Google Analytics