2.1 介绍

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

1  < security:ldap-server  />

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

    要开始在你的应用环境里使用security命名空间,你所需要的就是把架构声明添加到你的应用环境文件里:
1  < beans  xmlns ="http://www.springframework.org/schema/beans"
2  xmlns:security ="http://www.springframework.org/schema/security"
3  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
4  xsi:schemaLocation ="http://www.springframework.org/schema/beans [url]http://www.springframework.org/schema/beans/spring-beans-2.0.xsd[/url]
5  [url]http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd[/url]" >
6 
7  </ beans >

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

1  < beans:beans  xmlns ="http://www.springframework.org/schema/security"
2  xmlns:beans ="http://www.springframework.org/schema/beans" >
3 
4  </ 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 文件中:

1  < filter >
2  < filter-name > springSecurityFilterChain </ filter-name >
3  < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >
4  </ filter >
5 
6  < filter-mapping >
7  < filter-name > springSecurityFilterChain </ filter-name >
8  < url-pattern > /* </ url-pattern >
9  </ filter-mapping >
 
    这为Spring Security提供了一个调用钩子。 然后我们准备编辑application context文件。 web安全服务使用<http> 进行元素配置。

2.2.2 最小 <http>配置

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

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

    这表示,我们要保护应用程序中的所有URL,只有拥有 ROLE_USER角色的用户才能访问。
Note

    你可以使用多个<intercept-url>元素为不同URL的集合定义不同的访问需求,它们会被归入一个有序队列中,每次取出最先匹配的一个元素使用。 所以你必须把期望使用的匹配条件放到最上边。

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

1  < authentication-provider >
2  < user-service >
3  < user  name ="jimi"  password ="jimispassword"  authorities ="ROLE_USER, ROLE_ADMIN"   />
4  < user  name ="bob"  password ="bobspassword"  authorities ="ROLE_USER"   />
5  </ user-service >
6  </ authentication-provider >
 
    如果你熟悉以前的版本,你很可能已经猜到了这里是怎么回事。 <http>元素会创建一个FilterChainProxy和filter使用的bean。 以前常常出现的,因为filter顺序不正确产生的问题,不会再出现了,现在这些过滤器的位置都是预定义好的。

    <authentication-provider>元素创建了一个DaoAuthenticationProvider bean,<user-service>元素创建了一个InMemoryDaoImpl。 一个ProviderManager bean通常是由命名空间过程系统创建的, DaoAuthenticationProvider自动注册到它上面。

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

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

1  < http >
2  < intercept-url  pattern ="/**"  access ="ROLE_USER"   />
3  < form-login  />
4  < anonymous  />
5  < http-basic  />
6  < logout  />
7  < remember-me  />
8  </ http >

    这些元素分别与form-login,匿名认证,基本认证,注销处理和remember-me对应。 他们拥有各自的属性,来改变他们的具体行为。
auto-config需要一个UserDetailsService

    使用auto-config的时候如果没配置UserDetailsService就会出现错误(比如,如果你使用了LDAP认证)。 这是因为remember-me服务在auto-config="true"的时候启动了,它的认证机制需要UserDetailsService来实现(参考Remember-me章获得更多信息)。 如果你遇到了一个因为没定义UserDetailsService造成的问题,那就试着去掉auto-config配置(或者是其他你配置上的remember-me)。
2.2.2.2 表单和基本登录选项
    你也许想知道,在需要登录的时候,去×××这个登录页面,到现在为止我们都没有提到任何的HTML或JSP文件。 实际上,如果我们没有确切的指定一个页面用来登录,Spring Security会自动生成一个,基于可用的功能,为这个URL使用标准的数据,处理提交的登录,然后发送到默认的目标URL。 然而,命名空间提供了许多支持,让你可以自定义这些选项。 比如,如果你想实现自己的登录页面,你可以使用:

1  < http  auto-config ='true'>
2  <intercept-url pattern ="/login.jsp*"  filters ="none" />
3  < intercept-url  pattern ="/**"  access ="ROLE_USER"   />
4  < form-login  login-page ='/login.jsp'/>
5  </http >
 
    注意,你依旧可以使用auto-config。 这个form-login元素会覆盖默认的设置。 也要注意我们需要添加额外的intercept-url元素,指定用来做登录的页面的URL,这些URL不应该被安全filter处理。 否则,这些请求会被/**部分拦截,它没法访问到登录页面。 如果你想使用基本认证而不是表单登录,可以把配置修改成如下所示:

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

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

2.2.3 使用其他认证提供器

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

1  < authentication-provider  user-service-ref ='myUserDetailsService'/>
 
    如果你想用数据库,可以使用下面的方式

1  < authentication-provider >
2  < jdbc-user-service  data-source-ref ="securityDataSource" />
3  </ authentication-provider >

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