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属性指定。