Spring Security

<http>元素会创建一个FilterChainProxy 和filter 使用的bean,也可以在web.xml中自定义filter-name,不使用默认filterChainProxy的实现springSecurityFilterChain,可以自定义他

的实例MyLoginFilter,这个名字必须和过滤器类的名字一样。

<authentication-provider> 元素创建了一个DaoAuthenticationProvider bean ,<user-service>元素创建了一个InMemoryDaoImpl。所有authentication-provider 

元素必须作为<authentication-manager> 的子元素, 它创建了一个ProviderManager,并把authentication provider 注册到它里面

default-target-url,always-use-default-target 属性配置成"true",这样用户就会一直跳转到这一页

<authentication-provider user-service-ref='myUserDetailsService'/>表示自定义了一个Spring Security的UserDetailsService,下面可以这样写:

<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 用户信息的表。

另外,你可以配置一个SpringSecurity 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

下面是指定访问的端口信息:

<http>

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

</http>

检测失效的session ID,通过session-management的invalid-session-url="/sessionTimeout.htm"元素进行配置

首先,你需要把下面的监听器添加到你的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" error-if-maximum-exceeded="true" /> 防止用户第二次登陆
</session-management>
</http>

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

Spring Security框架维护一个过滤器链,来提供服务,也许你会将自己的过滤器加到链条的特定位置,这些可以通过直接配置bean 获得,过滤器按照次序排列在过滤器链中

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

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

<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>你还可以使用after 或before 属性

可以分别在position 属性使用"FIRST" 或"LAST"来指定你想让你的过滤器出现在队列元素的前面或后面,插入自定义的过滤器,而这个过滤器可能和命名空间自己创建的

标准过滤器放在同一个位置上,这样首要的是你不要错误包含命名空间的版本信息,避免使用auto-config属性,然后删除所有会创建这个过滤器的元素。

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

你可能想定义一个认证过滤器,并使用传统bean 语法定义一个入口点然后把它链接到命名空间里,就像我们已经看到的那样。对应的AuthenticationEntryPoint 可以使用<http> 

元素中的entry-point-ref 属性来进行设置

默认的AccessDecisionManager,当你使用命名空间配置时,默认的AccessDecisionManager 实例会自动注册,然后用来为方法调用和web URL 访问做验证

自定义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>

<authentication-manager>

<authentication-provider ref="casAuthenticationProvider"/>

</authentication-manager>

<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

另一个常见的需求是,上下文中的另一个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>

在3.0中,AnonymousAuthenticationFilter 已经成为了默认的<http>配置的一部分,所以<anonymous /> 元素无论是否设置auto-config都会被添加到配置中。

我们把安全主体和系统交互的信息都保存在SecurityContextHolder 中了,

用户查询Authentication 对象。你可以使用下面的代码

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {

String username = ((UserDetails)principal).getUsername();

} else {

String username = principal.toString();

}

大多数Spring Security 的验证机制都返回一个UserDetails 的实例作为主体。为了让你自己的用户数据库起作用,我们常常把UserDetails 转换成你系统提供的类

,这样你就可以直接调用业务相关的方法了(比如getEmail(), getEmployeeNumber()等等)

UserDetailsService。这个接口里的唯一一个方法,接收String 类型的 用户名参数,返回UserDetails

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,这是获得从Spring Security 中获得用户信息的最常用方法

当成功通过验证时, UserDetails 会被用来建立Authentication 对象保存在SecurityContextHolder 里

好消息是我们提供了好几个UserDetailsService实现,其中一个使用了内存中的map(InMemoryDaoImpl) 另一个而是用了JDBC(JdbcDaoImpl)。虽然,大多数用户倾向于写自

己的,使用这些实现常常放到已有的数据访问对象(DAO)上,表示它们的雇员,客户或其他企业应用中的用户。记住这个优势,无论你用什么UserDetailsService 返回的数

据都可以通过SecurityContextHolder 获得,就像上面的代码片段讲的一样。

GrantedAuthority除了主体,另一个Authentication 提供的重要方法是getAuthorities(),这个方法提供了GrantedAuthority 对象数组,GrantedAuthority 是赋予到主体的权限

这些权限通常使用角色表示, 比如ROLE_ADMINISTRATOR 或ROLE_HR_SUPERVISOR

GrantedAuthority 对象通常使用UserDetailsService 读取的,GrantedAuthority 对象是应用程序范围下的授权

SecurityContextHolder,提供几种访问SecurityContext 的方式,SecurityContext,保存Authentication 信息,和请求对应的安全信息

HttpSessionContextIntegrationFilter,为了在不同请求使用,把SecurityContext 保存到HttpSession 里

Authentication,展示Spring Security 特定的主体。

GrantedAuthority,反应,在应用程序范围你,赋予主体的权限。

UserDetails,通过你的应用DAO,提供必要的信息,构建Authentication 对象。

UserDetailsService,创建一个UserDetails,传递一个String 类型的用户名(或者证书ID 或其他)。

ExceptionTranslationFilter 是一个Spring Security 过滤器负责检测任何一个Spring Security 抛出的异常。

SecurityContextHolder.getContext().setAuthentication(anAuthentication), 然后Authentication 对象会反应到所有并发线程,共享相同的SecurityContext 实例。你可 

以自定义SecurityContextPersistenceFilter 的行为来创建完全新的一个线程避免影响其他的。还可以选择的是,你可以创建一个新实例,只在你暂时修改上下文的时候。这个

方法SecurityContextHolder.createEmptyContext()总会返回一个新的上下文实例。

DaoAuthenticationProvider

spring security 中最简单的AuthenticationProvider 实现是 DaoAuthenticationProvider , 这也是框架中最早支持的功能之一。它是UserDetailsService 的杠杆( 作为DAO ),

为了获得username, password 和GrantedAuthority 。它认证用户, 通过简单比较密码, 在UsernamePasswordAuthenticationToken 中,和UserDetailsService 中加载的信


<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">

<property name="userDetailsService" ref="inMemoryDaoImpl"/>

<property name="saltSource" ref bean="saltSource"/>

<property name="passwordEncoder" ref="passwordEcoder"/>

</bean>

UserDetailsService实现 大多数认证供应器都是用了UserDetails 和UserDetailsService接口。调用UserDetailsService 中的单独的方法

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;返回的UserDetails 是一个接口

它提供了获得保证非空的认证信息,比如用户名,密码,授予的权限和用户账号是可用还是禁用。大多数认证供应器会使用UserDetailsService, 

即使username 和password 没有实际用在这个认证决策中。它们可以使用返回的UserDetails 对象,获得它的GrantedAuthority 信息

这里的UserDetailsService 也很简单实现, 它应该为用户简单的获得认证信息,使用它们选择的持久化策略。这样说,Spring Security 包含了很多有用的基本实现,下面我们

会看到

一个简单的选择是使用安全命名空间中的

user-service 元素:

<user-service id="userDetailsService"> 

<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" /> 

<user name="bob" password="bobspassword" authorities="ROLE_USER" /> 

</user-service>

也支持使用外部的属性文件: <user-service id="userDetailsService" properties="users.properties"/>

JdbcDaoImpl

Spring Security 也包含了一个UserDetailsService, 它包含从一个JDBC 数据源中获得认证信息。内部使用了Spring JDBC,所以它避免了负责的功能完全的对象关系映射 

(ORM)只用来保存用户细节。如果你的应用使用了一个ORM 工具, 你应该写一个自己的UserDetailsService 重用你已经创建了的映射文件。返回到JdbcDaoImpl, 一个配

置的例子如下所示:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="org.hsqldb.jdbcDriver"/> 

<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>  

<property name="username" value="sa"/> 

<property name="password" value=""/>

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

JdbcDaoImpl 会假设用户的权限都保存在authorities 表中,参考JdbcDaoImpl 的Javadoc 以获得更多的信息

Spring Security 维护了一个过滤器链,它没有在内部使用servlet 或任何其他基于servlet 的框架(比如spring mvc), 所以它没有与任何特定的

web 技术强行关联。它只管处理HttpServletRequest 和HttpServletResponse

DelegatingFilterProxy

FilterChainProxy

在web.xml 中,然后在applicationcontext 中处理实体, 管理我们的web 安全bean。这就是FilterChainProxy 所做的事情。它使用DelegatingFilterProxy (就像上面例子中那 

样),但是对应的class 是org.springframework.security.web.FilterChainProxy。过滤器链是在applicationcontext 中声明的。这里有一个例子:

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**" filters="
securityContextPersistenceFilterWithASCFalse,
basicAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilterWithASCFalse,
formLoginFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>

filter-chain-map 被用来设置安全过滤器链。它映射一个特定的URL 模式,到过滤器链中,从bean 名称来定义的filters 元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值