- 浏览: 292833 次
- 性别:
- 来自: 唐山
最新评论
-
小灯笼:
JBPM5.4实战流程引擎开发网盘地址:https://pan ...
跟我学工作流——jBPM4视频教程(免费) -
Kai_Ge:
学会做人 写道临远大哥,谢谢你的贡献大名鼎鼎的临远!!膜拜中。 ...
Spring Security-3.0.1中文官方文档(翻译版) -
漂泊一剑客:
博主,你自己电脑上有下载,这些信息吗,能否分享一下给我
跟我学工作流——jBPM4视频教程(免费) -
Rookie_Li:
您好,您的教程很有用,请问例子的源码在哪下载?
spring security权限管理手册升级至spring security-3.1.3 -
nullFFF:
马教授 写道现在还用4有点过时了,最新的都已经是5.4了,目前 ...
跟我学工作流——jBPM4视频教程(免费)
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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
...
</beans>
在许多例子里,你会看到(在示例中)应用,我们通常使用"security"作为默认的命名空间,而不是"beans",这意味着我们可以省略所有security命名空间元素的前缀,使上下文更容易阅读。 如果你把应用上下文分割成单独的文件,让你的安全配置都放到其中一个文件里,这样更容易使用这种配置方法。 你的安全应用上下文应该像这样开头
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans">
...
</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提供了一个调用钩子。 然后我们准备编辑application context文件。 web安全服务使用<http> 进行元素配置。
2.2.2. 最小 <http>配置
只需要进行如下配置就可以实现安全配置:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
这表示,我们要保护应用程序中的所有URL,只有拥有 ROLE_USER角色的用户才能访问。
Note
你可以使用多个<intercept-url>元素为不同URL的集合定义不同的访问需求,它们会被归入一个有序队列中,每次取出最先匹配的一个元素使用。 所以你必须把期望使用的匹配条件放到最上边。
要是想添加一些用户,你可以直接使用下面的命名空间直接定义一些测试数据:
<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>
如果你熟悉以前的版本,你很可能已经猜到了这里是怎么回事。 <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属性,其实是下面这些配置的缩写:
<http>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login />
<anonymous />
<http-basic />
<logout />
<remember-me />
</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。 然而,命名空间提供了许多支持,让你可以自定义这些选项。 比如,如果你想实现自己的登录页面,你可以使用:
<http auto-config='true'>
<intercept-url pattern="/login.jsp*" filters="none"/>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page='/login.jsp'/>
</http>
注意,你依旧可以使用auto-config。 这个form-login元素会覆盖默认的设置。 也要注意我们需要添加额外的intercept-url元素,指定用来做登录的页面的URL,这些URL不应该被安全filter处理。 否则,这些请求会被/**部分拦截,它没法访问到登录页面。 如果你想使用基本认证而不是表单登录,可以把配置修改成如下所示:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
<http-basic />
</http>
基本身份认证会被优先用到,在用户尝试访问一个受保护的资源时,用来提示用户登录。 在这种配置中,表单登录依然是可用的,如果你还想用的话,比如,把一个登录表单内嵌到其他页面里。
2.2.3. 使用其他认证提供器
现实中,你会需要更大型的用户信息源,而不是写在application context里的几个名字。 多数情况下,你会想把用户信息保存到数据库或者是LDAP服务器里。 LDAP命名控件会在LDAP章里详细讨论,所以我们这里不会讲它。 如果你自定义了一个Spring Security的UserDetailsService实现,在你的application context中名叫"myUserDetailsService",然后你可以使用下面的验证。
<authentication-provider user-service-ref='myUserDetailsService'/>
如果你想用数据库,可以使用下面的方式
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource"/>
</authentication-provider>
这里的"securityDataSource"就是 DataSource bean在application context里的名字,它指向了包含着Spring Security用户信息的表。 另外,你可以配置一个Spring Security JdbcDaoImpl bean,使用user-service-ref属性指定。
2.2.3.1. 添加一个密码编码器
你的密码数据通常要使用一种散列算法进行编码。 使用<password-encoder>元素支持这个功能。 使用SHA加密密码,原始的认证供应器配置,看起来就像这样:
<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>
在使用散列密码时,用盐值防止字典攻击是个好主意,Spring Security也支持这个功能。 理想情况下,你可能想为每个用户随机生成一个盐值,不过,你可以使用从UserDetailsService读取出来的UserDetails对象中的属性。 比如,使用username属性,你可以这样用:
<password-encoder hash="sha">
<salt-source user-property="username"/>
</password-encoder>
你可以通过password-encoder的ref属性,指定一个自定义的密码编码器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>
你可以在Chapter 7, Channel Security找到更详细的讨论。
2.3.3. 同步Session控制
如果你希望限制单个用户只能登录到你的程序一次,Spring Security通过添加下面简单的部分支持这个功能。 首先,你需要把下面的监听器添加到你的web.xml文件里,让Spring Security获得session生存周期事件:
<listener>
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>
然后,在你的application context加入如下部分:
<http>
...
<concurrent-session-control max-sessions="1" />
</http>
这将防止一个用户重复登录好几次-第二次登录会让第一次登录失效。 通常我们更想防止第二次登录,这时候我们可以使用
<http>
...
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
</http>
第二次登录将被阻止。
2.3.4. OpenID登录
命名空间支持OpenID登录,替代普通的表单登录,或作为一种附加功能,只需要进行简单的修改:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
<openid-login />
</http>
你应该注册一个OpenID供应器(比如myopenid.com),然后把用户信息添加到你的内存<user-service>中:
<user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
你应该可以使用myopenid.com网站登录来进行验证了。
2.3.5. 添加你自己的filter
如果你以前使用过Spring Security,你应该知道这个框架里维护了一个过滤器链,来提供它的服务。 你也许想把你自己的过滤器添加到链条的特定位置,或者让已存在的过滤器,使用特定的版本。 你如何在命名空间配置里实现这些功能呢?过滤器链现在已经不能之间看到了。
过滤器顺序在使用命名空间的时候是被严格执行的。 每个Spring Security过滤器都实现了Spring的Ordered接口,这些过滤器在初始化的时候先被排好序了。 标准的过滤器在命名空间里都有自己的假名:
Table 2.1. 标准过滤器假名和顺序
Alias Filter Class
CHANNEL_FILTER ChannelProcessingFilter
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter
SESSION_CONTEXT_INTEGRATION_FILTER HttpSessionContextIntegrationFilter
LOGOUT_FILTER LogoutFilter
X509_FILTER X509PreAuthenticatedProcessigFilter
PRE_AUTH_FILTER Subclass of AstractPreAuthenticatedProcessingFilter
CAS_PROCESSING_FILTER CasProcessingFilter
AUTHENTICATION_PROCESSING_FILTER AuthenticationProcessingFilter
BASIC_PROCESSING_FILTER BasicProcessingFilter
SERVLET_API_SUPPORT_FILTER classname
REMEMBER_ME_FILTER RememberMeProcessingFilter
ANONYMOUS_FILTER AnonymousProcessingFilter
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter
NTLM_FILTER NtlmProcessingFilter
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor
SWITCH_USER_FILTER SwitchUserProcessingFilter
你可以把你自己的过滤器添加到队列中,使用custom-filter元素,使用这些名字中的一个,来指定你的过滤器应该出现的位置:
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</beans:bean>
你还可以使用after 或 before属性,如果你想把你的过滤器添加到队列中另一个过滤器的前面或后面。可以使用"FIRST" 或 "LAST"来指定你想让你的过滤器分别出现在队列元素的前面或后面。
2.3.6. 防止Session固定攻击
Session固定攻击是一个潜在危险,当一个恶意攻击者可以创建一个session访问一个网站的时候,然后说服另一个用户登录到同一个会话上(比如,发送给他们一个包含了session标识参数的链接)。 Spring Security通过在用户登录时,创建一个新session来防止这个问题。 如果你不需要保护,或者它与其他一些需求冲突,你可以通过使用<http>中的session-fixation-protection属性来配置它的行为,它有三个选项
*
migrateSession - 创建一个新session,把原来session中所有属性复制到新session中。这是默认值。
*
none - 什么也不做,继续使用原来的session。
*
newSession - 创建一个新的“干净的”session,不会复制session中的数据。
2.3.7. 设置自定义AuthenticationEntryPoint
如果你不使用命名空间里的表单登录,OpenID或基本身份验证,你也许想定义个验证过滤器和入口点,使用传统的bean语法,把他们链接到命名空间里。 你可以像Section 2.3.5, “添加你自己的filter”里解释的那样,添加过滤器。 对应的AuthenticationEntryPoint可以使用<http>中的entry-point-ref进行设置。
CAS例子,是一个在命名空间里使用自定义bean的好例子,包括这个语法。如果你不熟悉验证入口点,可以看看技术纵览章节中的讨论。
2.4. 保护方法
Spring Security 2.0大幅改善了对你的服务层方法添加安全。 如果你使用Java 5或更高版本,还支持JSR-250的安全注解,同框架提供的@secured注解相似。 你可以为单个bean提供安全控制,通过使用intercept-methods元素装饰bean声明,或者你可以使用AspectJ方式的切点来控制实体服务层里的多个bean。
2.4.1. <global-method-security>元素
这个元素用来在你的应用程序中启用基于安全的注解(通过在这个元素中设置响应的属性),也可以用来声明将要应用在你的实体application context中的安全切点组。 你应该只定义一个<global-method-security>元素。 下面的声明同时启用两种类型的注解:
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
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-url和protect-pointcut权限属性内容(和注解中的内容,如果你使用注解控制方法的权限)。
默认的策略是使用一个AffirmativeBased AccessDecisionManager ,以及RoleVoter 和AuthenticatedVoter。
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.5.2. 验证管理器
我们大概知道命名空间配置会自动为我们注册一个验证管理器bean。 这是一个Spring Security的ProviderManager类,如果你以前使用过框架,应该对它很熟悉了。
你也许想为ProviderManager注册另外的AuthenticationProvider bean,你可以使用<custom-authentication-provider>元素实现。比如:
<bean id="casAuthenticationProvider"
class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<security:custom-authentication-provider />
...
</bean>
另一个常见的需求是,上下文中的另一个bean可能需要引用AuthenticationManager。 这里有一个特殊的元素,可以让你为AuthenticationManager注册一个别名,然后你可以application context的其他地方使用这个名字。
<security:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<security:custom-filter position="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
...
</bean>
[1] 你可以在LDAP的章节里,找到更多有关使用的ldap-server的元素。
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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
...
</beans>
在许多例子里,你会看到(在示例中)应用,我们通常使用"security"作为默认的命名空间,而不是"beans",这意味着我们可以省略所有security命名空间元素的前缀,使上下文更容易阅读。 如果你把应用上下文分割成单独的文件,让你的安全配置都放到其中一个文件里,这样更容易使用这种配置方法。 你的安全应用上下文应该像这样开头
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans">
...
</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提供了一个调用钩子。 然后我们准备编辑application context文件。 web安全服务使用<http> 进行元素配置。
2.2.2. 最小 <http>配置
只需要进行如下配置就可以实现安全配置:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
这表示,我们要保护应用程序中的所有URL,只有拥有 ROLE_USER角色的用户才能访问。
Note
你可以使用多个<intercept-url>元素为不同URL的集合定义不同的访问需求,它们会被归入一个有序队列中,每次取出最先匹配的一个元素使用。 所以你必须把期望使用的匹配条件放到最上边。
要是想添加一些用户,你可以直接使用下面的命名空间直接定义一些测试数据:
<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>
如果你熟悉以前的版本,你很可能已经猜到了这里是怎么回事。 <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属性,其实是下面这些配置的缩写:
<http>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login />
<anonymous />
<http-basic />
<logout />
<remember-me />
</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。 然而,命名空间提供了许多支持,让你可以自定义这些选项。 比如,如果你想实现自己的登录页面,你可以使用:
<http auto-config='true'>
<intercept-url pattern="/login.jsp*" filters="none"/>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page='/login.jsp'/>
</http>
注意,你依旧可以使用auto-config。 这个form-login元素会覆盖默认的设置。 也要注意我们需要添加额外的intercept-url元素,指定用来做登录的页面的URL,这些URL不应该被安全filter处理。 否则,这些请求会被/**部分拦截,它没法访问到登录页面。 如果你想使用基本认证而不是表单登录,可以把配置修改成如下所示:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
<http-basic />
</http>
基本身份认证会被优先用到,在用户尝试访问一个受保护的资源时,用来提示用户登录。 在这种配置中,表单登录依然是可用的,如果你还想用的话,比如,把一个登录表单内嵌到其他页面里。
2.2.3. 使用其他认证提供器
现实中,你会需要更大型的用户信息源,而不是写在application context里的几个名字。 多数情况下,你会想把用户信息保存到数据库或者是LDAP服务器里。 LDAP命名控件会在LDAP章里详细讨论,所以我们这里不会讲它。 如果你自定义了一个Spring Security的UserDetailsService实现,在你的application context中名叫"myUserDetailsService",然后你可以使用下面的验证。
<authentication-provider user-service-ref='myUserDetailsService'/>
如果你想用数据库,可以使用下面的方式
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource"/>
</authentication-provider>
这里的"securityDataSource"就是 DataSource bean在application context里的名字,它指向了包含着Spring Security用户信息的表。 另外,你可以配置一个Spring Security JdbcDaoImpl bean,使用user-service-ref属性指定。
2.2.3.1. 添加一个密码编码器
你的密码数据通常要使用一种散列算法进行编码。 使用<password-encoder>元素支持这个功能。 使用SHA加密密码,原始的认证供应器配置,看起来就像这样:
<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>
在使用散列密码时,用盐值防止字典攻击是个好主意,Spring Security也支持这个功能。 理想情况下,你可能想为每个用户随机生成一个盐值,不过,你可以使用从UserDetailsService读取出来的UserDetails对象中的属性。 比如,使用username属性,你可以这样用:
<password-encoder hash="sha">
<salt-source user-property="username"/>
</password-encoder>
你可以通过password-encoder的ref属性,指定一个自定义的密码编码器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>
你可以在Chapter 7, Channel Security找到更详细的讨论。
2.3.3. 同步Session控制
如果你希望限制单个用户只能登录到你的程序一次,Spring Security通过添加下面简单的部分支持这个功能。 首先,你需要把下面的监听器添加到你的web.xml文件里,让Spring Security获得session生存周期事件:
<listener>
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>
然后,在你的application context加入如下部分:
<http>
...
<concurrent-session-control max-sessions="1" />
</http>
这将防止一个用户重复登录好几次-第二次登录会让第一次登录失效。 通常我们更想防止第二次登录,这时候我们可以使用
<http>
...
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
</http>
第二次登录将被阻止。
2.3.4. OpenID登录
命名空间支持OpenID登录,替代普通的表单登录,或作为一种附加功能,只需要进行简单的修改:
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
<openid-login />
</http>
你应该注册一个OpenID供应器(比如myopenid.com),然后把用户信息添加到你的内存<user-service>中:
<user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
你应该可以使用myopenid.com网站登录来进行验证了。
2.3.5. 添加你自己的filter
如果你以前使用过Spring Security,你应该知道这个框架里维护了一个过滤器链,来提供它的服务。 你也许想把你自己的过滤器添加到链条的特定位置,或者让已存在的过滤器,使用特定的版本。 你如何在命名空间配置里实现这些功能呢?过滤器链现在已经不能之间看到了。
过滤器顺序在使用命名空间的时候是被严格执行的。 每个Spring Security过滤器都实现了Spring的Ordered接口,这些过滤器在初始化的时候先被排好序了。 标准的过滤器在命名空间里都有自己的假名:
Table 2.1. 标准过滤器假名和顺序
Alias Filter Class
CHANNEL_FILTER ChannelProcessingFilter
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter
SESSION_CONTEXT_INTEGRATION_FILTER HttpSessionContextIntegrationFilter
LOGOUT_FILTER LogoutFilter
X509_FILTER X509PreAuthenticatedProcessigFilter
PRE_AUTH_FILTER Subclass of AstractPreAuthenticatedProcessingFilter
CAS_PROCESSING_FILTER CasProcessingFilter
AUTHENTICATION_PROCESSING_FILTER AuthenticationProcessingFilter
BASIC_PROCESSING_FILTER BasicProcessingFilter
SERVLET_API_SUPPORT_FILTER classname
REMEMBER_ME_FILTER RememberMeProcessingFilter
ANONYMOUS_FILTER AnonymousProcessingFilter
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter
NTLM_FILTER NtlmProcessingFilter
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor
SWITCH_USER_FILTER SwitchUserProcessingFilter
你可以把你自己的过滤器添加到队列中,使用custom-filter元素,使用这些名字中的一个,来指定你的过滤器应该出现的位置:
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
</beans:bean>
你还可以使用after 或 before属性,如果你想把你的过滤器添加到队列中另一个过滤器的前面或后面。可以使用"FIRST" 或 "LAST"来指定你想让你的过滤器分别出现在队列元素的前面或后面。
2.3.6. 防止Session固定攻击
Session固定攻击是一个潜在危险,当一个恶意攻击者可以创建一个session访问一个网站的时候,然后说服另一个用户登录到同一个会话上(比如,发送给他们一个包含了session标识参数的链接)。 Spring Security通过在用户登录时,创建一个新session来防止这个问题。 如果你不需要保护,或者它与其他一些需求冲突,你可以通过使用<http>中的session-fixation-protection属性来配置它的行为,它有三个选项
*
migrateSession - 创建一个新session,把原来session中所有属性复制到新session中。这是默认值。
*
none - 什么也不做,继续使用原来的session。
*
newSession - 创建一个新的“干净的”session,不会复制session中的数据。
2.3.7. 设置自定义AuthenticationEntryPoint
如果你不使用命名空间里的表单登录,OpenID或基本身份验证,你也许想定义个验证过滤器和入口点,使用传统的bean语法,把他们链接到命名空间里。 你可以像Section 2.3.5, “添加你自己的filter”里解释的那样,添加过滤器。 对应的AuthenticationEntryPoint可以使用<http>中的entry-point-ref进行设置。
CAS例子,是一个在命名空间里使用自定义bean的好例子,包括这个语法。如果你不熟悉验证入口点,可以看看技术纵览章节中的讨论。
2.4. 保护方法
Spring Security 2.0大幅改善了对你的服务层方法添加安全。 如果你使用Java 5或更高版本,还支持JSR-250的安全注解,同框架提供的@secured注解相似。 你可以为单个bean提供安全控制,通过使用intercept-methods元素装饰bean声明,或者你可以使用AspectJ方式的切点来控制实体服务层里的多个bean。
2.4.1. <global-method-security>元素
这个元素用来在你的应用程序中启用基于安全的注解(通过在这个元素中设置响应的属性),也可以用来声明将要应用在你的实体application context中的安全切点组。 你应该只定义一个<global-method-security>元素。 下面的声明同时启用两种类型的注解:
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
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-url和protect-pointcut权限属性内容(和注解中的内容,如果你使用注解控制方法的权限)。
默认的策略是使用一个AffirmativeBased AccessDecisionManager ,以及RoleVoter 和AuthenticatedVoter。
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.5.2. 验证管理器
我们大概知道命名空间配置会自动为我们注册一个验证管理器bean。 这是一个Spring Security的ProviderManager类,如果你以前使用过框架,应该对它很熟悉了。
你也许想为ProviderManager注册另外的AuthenticationProvider bean,你可以使用<custom-authentication-provider>元素实现。比如:
<bean id="casAuthenticationProvider"
class="org.springframework.security.providers.cas.CasAuthenticationProvider">
<security:custom-authentication-provider />
...
</bean>
另一个常见的需求是,上下文中的另一个bean可能需要引用AuthenticationManager。 这里有一个特殊的元素,可以让你为AuthenticationManager注册一个别名,然后你可以application context的其他地方使用这个名字。
<security:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<security:custom-filter position="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
...
</bean>
[1] 你可以在LDAP的章节里,找到更多有关使用的ldap-server的元素。
评论
3 楼
hspeed
2008-07-05
配置是简单了,但搞不懂是怎么个原理啊,比方说“j_spring_security_check”这种url是在哪个文件里面定义的啊,它默认的登陆页面在哪个包里面?另外对楼主的翻译赞一个。
2 楼
kevindurant
2008-06-26
弄了老半天不知道..认证的接口怎么弄..我水平悠闲 文档里面找不到什么答案...要把用户
.资源这些信息都放ldap 或者 数据库 怎么来的..看了官方的例子用hsqldb 我甚至还不明白他是怎么验证的..
.资源这些信息都放ldap 或者 数据库 怎么来的..看了官方的例子用hsqldb 我甚至还不明白他是怎么验证的..
1 楼
lynn.wong
2008-06-05
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource"/>
</authentication-provider>
这种通过数据库来授权的情况能否详细些?原文档中也不是很详细。
谢谢。
<jdbc-user-service data-source-ref="securityDataSource"/>
</authentication-provider>
这种通过数据库来授权的情况能否详细些?原文档中也不是很详细。
谢谢。
发表评论
-
spring security权限管理手册升级至spring security-3.1.3
2012-12-08 01:01 12296费了半天劲,终于把原来基于spring security 2. ... -
请把acegi替换成Spring Security(内附视频)
2010-03-22 09:54 6562在对web项目进行权限管理时,采用的方法无非是写一大堆JSP或 ... -
Spring Security-3.0.1中文官方文档(翻译版)
2010-01-19 09:36 10644这次发布的Spring Security-3.0.1是一个bu ... -
敬献Spring Security-3.x官方文档中文版
2009-12-29 11:43 10879Spring Security-3.x新近发布,整体的项 ... -
【分享】《基于Spring Security的ACL实现与扩展》内附ppt下载
2009-09-21 09:43 3451上次朋友间技术交流整理的ppt文档,因为之前一直在整理Spri ... -
Spring Security 安全权限管理手册(0.1.0更新)
2009-08-05 10:26 5034随着内容的堆叠,文档结构开始渐渐混乱了,到0.1.0为止关于认 ... -
Spring Security 安全权限管理手册(0.0.9更新)
2009-07-27 09:27 3278这次更新中包含了一个在用户输入密码错误三次后锁定账户的示 ... -
Spring Security 安全权限管理手册(0.0.8更新)
2009-07-20 09:58 1890Spring Security-2.0.5发布,这个bug ... -
Spring Security 安全权限管理手册(0.0.7更新)
2009-07-13 00:38 3196这一次迭代,对章节的命名进行了这里,目标是尽快覆盖Spring ... -
Spring Security 安全权限管理手册(0.0.6更新)
2009-07-10 01:54 1669这一次,我们添加了taglib标签库的时候,以及如何使用多种方 ... -
Spring Security手册更新cas, basic, acl
2009-06-29 18:13 2670这次更新的都是重头戏,CAS和ACL。其中ACL只是简述了Sp ... -
Spring Security手册更新——添加“管理会话”和对namespace,database
2009-06-22 10:04 1942新增的部分有,第八章“管理会话”,附录D,E分别整 ... -
图解Spring Security默认使用的过滤器
2009-06-15 10:38 3860第 9 章 图解过滤器 图 9.1. au ... -
Spring Security-2.0导航-基础篇,又添两章
2009-06-10 10:31 1916目前我们在基础篇中已经编写了六章,基本上可 ... -
Spring Security-2.0入门教程(基础篇)
2009-06-04 17:48 4775欢迎阅读咱们写的Spring Security教程,咱们既不想 ... -
springsecurity-2.x官方文档中文翻译初步整理完成,附上几个例子
2008-08-17 11:12 7891预览地址:http://family168.com/tutor ... -
(翻译)Spring Security-2.0.x参考文档“领域对象安全”
2008-08-13 00:18 2199领域对象安全 24.1. 概述 请注意:在2.0.0之前,S ... -
(翻译)Spring Security-2.0.x参考文档“安全对象实现”
2008-08-12 09:50 2027安全对象实现 23.1. AOP联盟 (MethodInvoc ... -
(翻译)Spring Security-2.0.x参考文档“通用授权概念”
2008-08-11 18:22 2820通用授权概念 22.1. 授权 在认证部分简略提过了,所有的 ... -
(翻译)Spring Security-2.0.x参考文档“安全数据库表结构”
2008-08-10 09:52 2035安全数据库表结构 可以为框架采用不同的数据库结构,这个附录为 ...
相关推荐
包含翻译后的API文档:spring-security-core-5.3.9.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-core:5.3.9.RELEASE; 标签:springframework、security...
spring-beans-2.0.xsd
包含翻译后的API文档:spring-security-oauth2-2.3.5.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security.oauth:spring-security-oauth2:2.3.5.RELEASE; 标签:spring、security...
包含翻译后的API文档:spring-security-core-5.2.0.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-core:5.2.0.RELEASE; 标签:springframework、security...
包含翻译后的API文档:spring-security-rsa-1.0.10.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-rsa:1.0.10.RELEASE; 标签:spring、rsa、security、...
包含翻译后的API文档:spring-security-jwt-1.0.10.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-jwt:1.0.10.RELEASE; 标签:spring、security、jwt、...
包含翻译后的API文档:spring-security-web-5.2.0.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-web:5.2.0.RELEASE; 标签:springframework、security、...
spring-dwr-2.0.xsd spring 与 DWR进行配置
spring-boot-starter-web-2.0.7.0.jar
Struts2-Spring-Plugin-2.0.11.1版本是在2.0.11.1时期发布的,可能包含了一些特定的修复和优化,具体可以查阅该版本的发行说明或官方文档,以了解其特性、改进和已知问题。 在使用这个插件时,你需要在Struts2的...
包含翻译后的API文档:spring-boot-actuator-autoconfigure-2.3.12.RELEASE-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.springframework.boot:spring-boot-actuator-autoconfigure:2.3.12....
包含翻译后的API文档:spring-security-oauth2-2.3.5.RELEASE-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.springframework.security.oauth:spring-security-oauth2:2.3.5.RELEASE; 标签:spring...
包含翻译后的API文档:spring-security-core-5.0.7.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-core:5.0.7.RELEASE; 标签:springframework、security...
包含翻译后的API文档:spring-security-crypto-5.6.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-crypto:5.6.1; 标签:spring、security、springframework、...
包含翻译后的API文档:spring-security-jwt-1.0.10.RELEASE-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.springframework.security:spring-security-jwt:1.0.10.RELEASE; 标签:spring、security...
然而,随着技术的发展,现代的Web应用更倾向于使用Spring Boot这样的微服务框架,以简化配置和提升开发效率。但了解并掌握SSH2框架的搭建和使用,对于理解Web应用的架构和设计模式仍然具有重要的学习价值。
包含翻译后的API文档:spring-security-crypto-5.5.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-crypto:5.5.2; 标签:springframework、security、spring、...
包含翻译后的API文档:spring-security-config-5.2.0.RELEASE-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.springframework.security:spring-security-config:5.2.0.RELEASE; 标签:springframework、...
spring-framework-2.0-with-dependencies.zip spring-framework-2.0-with-dependencies.zip spring-framework-2.0-with-dependencies.zip spring-framework-2.0-with-dependencies.zip spring-framework-2.0-with-...