《spring安全框架系列springSecurity之我见》总纲 [转帖]_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4593 | 回复: 0   主题: 《spring安全框架系列springSecurity之我见》总纲 [转帖]        下一篇 
    本主题由 koei 于 2012-2-15 19:29:10 移动
barry
注册用户
等级:中校
经验:1534
发帖:236
精华:2
注册:2012-1-13
状态:离线
发送短消息息给barry 加好友    发送短消息息给barry 发消息
发表于: IP:您无权察看 2012-2-14 10:49:38 | [全部帖] [楼主帖] 楼主

使用一个新的框架之前,首先我们来认识一下springSecurity,毕竟框架这种东西有时靠不住,所以学到他的思想才是最重要的,很多人都知道这么用,具体为什么,没有人告诉我们,首先我们从最基本的看起,了解一些入门知识是有必要的:

1.4.1.1. Core -spring-security-core.jar

包含了核心认证和权限控制类和接口, 运程支持和基本供应 API。使用 Spring Security

所必须的。支持单独运行的应用, 远程客户端,方法(服务层)安全和 JDBC 用户供应。

包含顶级包:

org.springframework.security.core
org.springframework.security.access
org.springframework.security.authentication
org.springframework.security.provisioning
org.springframework.security.remoting
1.4.1.2. Web -spring-security-web.jar


包含过滤器和对应的 web 安全架构代码。任何需要依赖 servlet API 的。 你将需要它,如

果 你 需 要 Spring Security Web 认 证 服 务 和 基 于 URL 的 权 限 控 制 。 主 包 是

org.springframework.security.web。
1.4.1.3. Config -spring-security-config.jar


包含安全命名控制解析代码(因此我们不能直接把它用在你的应用中)。你需要它, 如果使用了SpringSecurityXML命名控制来进行配置。主包是

org.springframework.security.config。
1.4.1.4. LDAP -spring-security-ldap.jar


LDAP 认证和实现代码,如果你需要使用 LDAP 认证或管理 LDAP 用户实体就是必须的。顶

级包是org.springframework.security.ldap。

1.4.1.5. ACL -spring-security-acl.jar

处理领域对象 ACL 实现。用来提供安全给特定的领域对象实例,在你的应用中。 顶级包是

org.springframework.security.acls。
1.4.1.6. CAS -spring-security-cas-client.jar


Spring Security 的 CAs 客户端集成。如果你希望使用 Spring Security web 认证 整合

一个 CAS 单点登录服务器。顶级包是 org.springframework.security.cas。

1.4.1.7. OpenID -spring-security-openid.jar

OpenID web 认 证 支 持 。 用 来 认 证 用 户 , 通 过 一 个 外 部 的 OpenID 服 务 。

org.springframework.security.openid。需要 OpenID4Java。

在许多例子里,你会看到(在示例中)应用,我们通常使用"security"作为默认的命名空间,

而不是"beans",这意味着我们可以省略所有 security 命名空间元素的前缀,使上下文更

容易阅读。 如果你把应用上下文分割成单独的文件,让你的安全配置都放到其中一个文件

里,这样更容易使用这种配置方法。 你的安全应用上下文应该像这样开头:

[html]view plaincopyprint?

  1. <beans:beansxmlns="http://www.springframework.org/schema/security"
  2. xmlns:beans="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  6. http://www.springframework.org/schema/security  
  7. http://www.springframework.org/schema/security/spring-security-3.0.xsd">
  8. ...  
  9. </beans:beans>

<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.1. 配置 web.xml

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

[html]view plaincopyprint?

  1. <filter>
  2. <filter-name>springSecurityFilterChain</filter-name>
  3. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>springSecurityFilterChain</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

<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 是一个 SpringFramework 的类,它可以代理一个 applicationcontext 中定义的 Springbean 所实现的 filter。 这种情况下,bean 的名字是"springSecurityFilterChain",这是由命名空间创建的用于处理 web 安全的一个内部的机制。 注意,你不应该自己使用这个bean 的 名 字 。 一 旦 你 把 这 个 添 加 到 你 的 web.xml 中 , 你 就 准 备 好 开 始 编 辑 呢 applicationcontext 文件了。 web 安全服务是使用<http>元素配置的。

2.2.2. 最小 <http>配置

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

[html]view plaincopyprint?

  1. <httpauto-confighttpauto-config='true'>
  2. <intercept-urlpatternintercept-urlpattern="/**"access="ROLE_USER"/>
  3. </http>


<httpauto-config='true'> <intercept-urlpattern="/**" access="ROLE_USER" /> </http>

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

<http>元素是 所有 web 相关的命名空间功能的上级元素。<intercept-url>元素定义了

pattern,用来匹配进入的请求 URL,使用一个 ant 路径语法。 access 属性定义了请求

匹配了指定模式时的需求。使用默认的配置, 这个一般是一个逗号分隔的角色队列,一个

用户中的一个必须被允许访问请求。 前缀“ROLE_”表示的是一个用户应该拥有的权限比

对。换句话说, 一个普通的基于角色的约束应该被使用。Spring Security 中的访问控制

不限于简单角色的应用 (因此,我们使用不同的前缀来区分不同的安全属性)

你可以使用多个<intercept-url>元素为不同 URL 的集合定义不同的访问需求, 它们会被

归入一个有序队列中,每次取出最先匹配的一个元素使用。 所以你必须把期望使用的匹配

条 件 放 到 最 上 边 。 你 也 可 以 添 加 一 个 method 属 性 来 限 制 匹 配 一 个 特 定 的 HTTP

method(GET,POST, PUT 等等)。对于一个模式同时定义在定义了 method 和未定义

method 的情况, 指定 method 的匹配会无视顺序优先被使用。

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

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-provider>
  3. <user-service>
  4. <user name="jimi" password="jimispassword" authorities="ROLE_USER,ROLE_ADMIN"/>
  5. <usernameusername="bob"password="bobspassword" authorities="ROLE_USER"/>
  6. </user-service>
  7. </authentication-provider>
  8. </authentication-manager>

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


这些过滤器的位置都是预定义好的。

<authentication-provider> 元 素 创 建 了 一 个 DaoAuthenticationProvider bean ,

<user-service>元素创建了一个 InMemoryDaoImpl。 所有 authentication-provider元 素 必 须 作 为<authentication-manager> 的 子 元 素 ,它 创 建 了 一 个ProviderManager,并把 authentication provider 注册到它里面。 你可以在命名空间附中找到关于创建这个 bean 的更新信息。很值得去交叉检查一下这里,如果你希望开始理解框架中哪些是重要的类 以及它们是如何使用的,特别是如果你希望以后做一些自定义工作。

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

现在,你可以启动程序,然后就会进入登录流程了。 试试这个,或者试试工程里的“tutorial”

例子. 上述配置实际上把很多服务添加到了程序里,因为我们使用了 auto-config 属性。

比如,表单登录和"remember-me"服务自动启动了。

2.2.2.1. auto-config 包含了什么?

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

[html]view plaincopyprint?

  1. <http>
  2. <form-login/>
  3. <http-basic/>
  4. <logout/>
  5. </http>

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


这些元素分别与 form-login,基本认证和注销处理对应。

他们拥有各自的属性,来改

变他们的具体行为。

2.2.2.2. 表单和基本登录选项

你也许想知道,在需要登录的时候,去哪里找这个登录页面,到现在为止我们都没有提到任

何的 HTML 或 JSP 文件。 实际上,如果我们没有确切的指定一个页面用来登录, Spring

Security 会自动生成一个,基于可用的功能,为这个 URL 使用标准的数据,处理提交的登

录,然后在登陆后发送到默认的目标 URL。 然而,命名空间提供了许多支持,让你可以自

定义这些选项。 比如,如果你想实现自己的登录页面,你可以使用:

[html]view plaincopyprint?

  1. <http auto-config='true'>
  2. <intercept-urlpatternintercept-urlpattern="/login.jsp*"access="IS_AUTHENTICATED_ANONYMOUSLY"/>
  3. <intercept-urlpatternintercept-urlpattern="/**"access="ROLE_USER"/>
  4. <form-loginlogin-pageform-loginlogin-page='/login.jsp'/>
  5. </http>

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


注意,你依旧可以使用 auto-config。 这个 form-login 元素会覆盖默认的设置。 也要注

意我们需要添加额外的 intercept-url 元素,指定用来做登录的页面的 URL, 这些 URL 应

该可以被匿名访问。[4] 否则,这些请求会被/**部分拦截,它没法访问到登录页面。 这是

一个很常见的配置错误,它会导致系统出现无限循环。 Spring Security 会在日志中发出

一个警告,如果你的登录页面是被保护的。 也可能让所有的请求都匹配特定的模式,通过

完全的安全过滤器链:

[html]view plaincopyprint?

  1. <http auto-config='true'>
  2. <intercept-urlpatternintercept-urlpattern="/css/**"filters="none"/>
  3. <intercept-urlpatternintercept-urlpattern="/login.jsp*"filters="none"/>
  4. <intercept-urlpatternintercept-urlpattern="/**"access="ROLE_USER"/>
  5. <form-loginlogin-page='/login.jsp'/>
  6. </http>

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


主要的是意识到这些请求会被完全忽略,对任何 Spring Security 中 web 相关的配置,或

额外的属性,比如requires-channel, 所以你会不能访问当前用户信息,或调用被保护

方法,在请求过程中。 使用access='IS_AUTHENTICATED_ANONYMOUSLY'作为一个

选择方式 如果你还想要安全过滤器链起作用。

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

[html]view plaincopyprint?

  1. <httpauto-confighttpauto-config='true'>
  2. <intercept-urlpatternintercept-urlpattern="/**"access="ROLE_USER"/>
  3. <http-basic/>
  4. </http>

<httpauto-config='true'> <intercept-urlpattern="/**" access="ROLE_USER" /> <http-basic /> </http>


基本身份认证会被优先用到,在用户尝试访问一个受保护的资源时,用来提示用户登录。 在

这种配置中,表单登录依然是可用的,如果你还想用的话,比如,把一个登录表单内嵌到其

他页面里。

2.2.2.2.1.

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

如果在进行表单登陆之前,没有试图去访问一个被保护的资源,default-target-url 就会起作用。

这 是 用 户 登 陆 后 会 跳 转 到 的 URL , 默 认 是 "/" 。你也可以把always-use-default-target 属性配置成"true",这样用户就会一直跳转到这一页(无论登陆是“跳转过来的”还是用户特定进行登陆)。 如果你的系统一直需要用户从首页进入,就可以使用它了,比如:

[html]view plaincopyprint?

  1. <http>
  2. <intercept-urlpatternintercept-urlpattern='/login.htm*'filters='none'/>
  3. <intercept-urlpatternintercept-urlpattern='/**'access='ROLE_USER'/>
  4. <form-loginlogin-pageform-loginlogin-page='/login.htm'default-target-url='/home.htm'
  5. always-use-default-target='true'/>
  6. </http>

<http> <intercept-urlpattern='/login.htm*' filters='none'/> <intercept-urlpattern='/**' access='ROLE_USER' /> <form-loginlogin-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实现,在你applicationcontext中 名 叫"myUserDetailsService",然后你可以使用下面的验证。

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-provideruser-service-refauthentication-provideruser-service-ref='myUserDetailsService'/>
  3. </authentication-manager>

<authentication-manager> <authentication-provideruser-service-ref='myUserDetailsService'/> </authentication-manager>


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

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-provider>
  3. <jdbc-user-servicedata-source-refjdbc-user-servicedata-source-ref="securityDataSource"/>
  4. </authentication-provider>
  5. </authentication-manager>

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


这里的“securityDataSource”就是 DataSource bean 在 application context 里的名

字,它指向了包含着 Spring Security 用户信息的表。 另外,你可以配置一个 Spring

SecurityJdbcDaoImpl bean,使用user-service-ref 属性指定:

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-provideruser-service-refauthentication-provideruser-service-ref='myUserDetailsService'/>
  3. </authentication-manager>
  4. <beans:beanidbeans:beanid="myUserDetailsService"
  5. class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
  6. <beans:propertynamebeans:propertyname="dataSource"ref="dataSource"/>
  7. </beans:bean>

<authentication-manager> <authentication-provideruser-service-ref='myUserDetailsService'/> </authentication-manager> <beans:beanid="myUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <beans:propertyname="dataSource" ref="dataSource"/> </beans:bean>


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

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-providerrefauthentication-providerref='myAuthenticationProvider'/>
  3. </authentication-manager>


<authentication-manager> <authentication-providerref='myAuthenticationProvider'/> </authentication-manager>

这里myAuthenticationProvider 是你的 applicationcontext 中的一个 bean 的名字,

它实现了AuthenticationProvider。 查看 Section 2.6, “验证管理器和命名空间 ”了解更多信

息,AuthenticationManager 使用命名空间在 Spring Security 中是如何配置的。

2.2.3.1. 添加一个密码编码器

你的密码数据通常要使用一种散列算法进行编码。 使用<password-encoder>元素支持

这个功能。 使用 SHA 加密密码,原始的认证供应器配置,看起来就像这样:

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-provider>
  3. <password-encoderhashpassword-encoderhash="sha"/>
  4. <user-service>
  5. <usernameusername="jimi"password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"  
  6. authorities="ROLE_USER,ROLE_ADMIN"/>
  7. <usernameusername="bob"password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f"
  8. authorities="ROLE_USER"/>
  9. </user-service>
  10. </authentication-provider>
  11. </authentication-manager>

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


在使用散列密码时,用盐值防止字典攻击是个好主意,Spring Security 也支持这个功能。

理想情况下,你可能想为每个用户随机生成一个盐值,不过,你可以使用 从

UserDetailsService 读取出来的 UserDetails 对象中的属性。 比如,使用 username 属

性,你可以这样用:

[html]view plaincopyprint?

  1. <password-encoderhashpassword-encoderhash="sha">
  2. <salt-sourceuser-propertysalt-sourceuser-property="username"/>
  3. </password-encoder>


<password-encoderhash="sha"> <salt-sourceuser-property="username"/> </password-encoder>

你可以通过password-encoder 的 ref 属性,指定一个自定义的密码编码器 bean。 这应

该 包 含 applicationcontext 中 一 个 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 属性:

[html]view plaincopyprint?

  1. <http>
  2. <intercept-urlpatternintercept-urlpattern="/secure/**"access="ROLE_USER"requires-channel="https"/>
  3. <intercept-urlpatternintercept-urlpattern="/**"access="ROLE_USER"requires-channel="any"/>
  4. ...  
  5. </http>

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


使用了这个配置以后,如果用户通过 HTTP 尝试访问"/secure/**"匹配的网址,他们会先

被重定向到 HTTPS 网址下。 可用的选项有"http","https" 或 "any"。 使用"any"意味

着使用 HTTP 或 HTTPS 都可以。

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

关系:

[html]view plaincopyprint?

  1. <http>
  2. ...  
  3. <port-mappings>
  4. <port-mappinghttpport-mappinghttp="9080"https="9443"/>
  5. </port-mappings>
  6. </http>

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


2.3.3. 会话管理

2.3.3.1. 检测超时

你可以配置 Spring Security 检测失效的 session ID, 并把用户转发到对应的 URL。这

可 以通 过session-management 元 素配 置:

[html]view plaincopyprint?

  1. <http>
  2. ...  
  3. <session-management invalid-session-url="/sessionTimeout.htm"/>
  4. </http>

<http> ... <session-management invalid-session-url="/sessionTimeout.htm"/> </http>


2.3.3.2. 同步会话控制

如果你希望限制单个用户只能登录到你的程序一次,Spring Security 通过添加下面简单的

部分支持这个功能。首先,你需要把下面的监听器添加到你的 web.xml 文件里,让 Spring

Security 获 得 session 生 存 周 期 事 件 :

[html]view plaincopyprint?

  1. <listener>
  2. <listener-class>
  3. org.springframework.security.web.session.HttpSessionEventPublisher  
  4. </listener-class>
  5. </listener>

<listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener>


然后,在你的 applicationcontext 加入如下部分:

[html]view plaincopyprint?

  1. <http>
  2. ...  
  3. <session-management>
  4. <concurrency-controlmax-sessionsconcurrency-controlmax-sessions="1"/>
  5. </session-management>
  6. </http>

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


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

二次登录,这时候我们可以使用

[html]view plaincopyprint?

  1. <http>
  2. ...  
  3. <session-management>
  4. <concurrency-controlmax-sessionsconcurrency-controlmax-sessions="1"error-if-maximum-exceeded="true"/>
  5. </session-management>
  6. </http>


<http> ... <session-management> <concurrency-controlmax-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.4.1.1. 使用protect-pointcut 添加安全切点

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

参考下面的例子:

[html]view plaincopyprint?

  1. <global-method-security>
  2. <protect-pointcutexpressionprotect-pointcutexpression="execution(* com.mycompany.*Service.*(..))"
  3. access="ROLE_USER"/>
  4. </global-method-security>

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


这样会保护 applicationcontext 中的符合条件的 bean 的所有方法,这些 bean 要在

com.mycompany 包下,类名以"Service"结尾。 ROLE_USER 的角色才能调用这些方

法。 就像 URL 匹配一样,指定的匹配要放在切点队列的最前面,第一个匹配的表达式才会

被用到。

2.5. 默认的AccessDecisionManager

这章假设你有一些 Spring Security 权限控制有关的架构知识。 如果没有,你可以跳过这

段,以后再来看,因为这章只是为了自定义的用户设置的,需要在简单基于角色安全的基础

上加一些客户化的东西。

当你使用命名空间配置时,默认的 AccessDecisionManager 实例会自动注册,然后用来

为 方 法 调 用 和 web URL 访 问 做 验 证 , 这 些 都 是 基 于 你 设 置 的 intercept-url 和

protect-pointcut 权限属性内容(和注解中的内容,如果你使用注解控制方法的权限)。

默认的策略是使用一个 AffirmativeBased AccessDecisionManager ,以及 RoleVoter

和AuthenticatedVoter。 可以在 authorization 中获得更多信息。

2.5.1. 自定义AccessDecisionManager

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

对于方法安全,你可以设置 global-security 里的access-decision-manager-ref 属性,

用对应AccessDecisionManager bean 在 applicationcontext 里的 id:

[html]view plaincopyprint?

  1. <global-method-securityaccess-decision-manager-refglobal-method-securityaccess-decision-manager-ref="myAccessDecisionManagerBean">
  2. ...  
  3. </global-method-security>

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


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

[html]view plaincopyprint?

  1. <httpaccess-decision-manager-refhttpaccess-decision-manager-ref="myAccessDecisionManagerBean">
  2. ...  
  3. </http>


<httpaccess-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 的名字,比如:

[html]view plaincopyprint?

  1. <authentication-manager>
  2. <authentication-providerrefauthentication-providerref="casAuthenticationProvider"/>
  3. </authentication-manager>
  4. <beanid="casAuthenticationProvider"
  5. class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
  6. <security:custom-authentication-provider/>
  7. ...  
  8. </bean>

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


另一个常见的需求是,上下文中的另一个 bean 可能需要引用AuthenticationManager。

你可以为AuthenticationManager 注册一个别名,然后在 applicationcontext 的其他

地方使用这个名字。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论