spring-scurity

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<!-- ======================== FILTER CHAIN =======================
FilterChainProxy will transfer these filters by order to make them use the Ioc of spring.
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON define that convert url to lowrcase befor comparing
PATTERN_TYPE_APACHE_ANT define that use the model of apache ant.
-->

<!-- 目标委托的bean 下面的value就是多个过滤器的组合成过滤链 这个bean是web.xml的
filterChainProx的委托目标。
注意顺序.
-->
<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
<!-- Put channelProcessingFilter before securityContextHolderAwareRequestFilter to turn on SSL switching -->
<!-- It's off by default b/c Canoo WebTest doesn't support SSL out-of-the-box -->
</property>
</bean>
<!-- 过滤器链中的过滤器 通过HttpSession转存SecurityContext的过滤器.如果用户还为通过认证,httpSessionContextIntegrationFilter
在HttpSession中找不到对应的SecurityContext这时authenticationProcessingFilter将启动正常的认证流程,反之,如果通过认证,
SecurityContext将直接从HttpSession中取出。-->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />

<!-- SecurityContext 保存在HttpSession中,当用户退出系统的时候必须清楚,否则其会一直保存于HttpSession中,直到session过期才被清除
通常推出系统会记录日志,将登录信息保存到cookie里面等。LogoutFilter接口 -->
<bean id="logoutFilter"
class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/login.jsp" /><!-- 退出系统时候后转向的URL-->
<!-- URL redirected to after logout -->
<constructor-arg>
<list>

<ref bean="rememberMeServices" />

<!-- SecurityContextLogoutHandler是LogoutFilter的一个实现类,是将SecurityContext从HttpSession中删除
另一个是:TokenBasedRememberMeServices,是将Authentication中的用户名和密码保存到客户端的cookie里面,以便下次
用户访问的时候直接通过cookie里取 -->
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.jsp" /><!-- 指定推出系统的URL请求 -->
</bean>
<!-- 使用认证处理过滤器处理匹配的url. -->
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<!--其实AuthenticationProcessingFilter只是从页面获取用户信息,根据认证结果完成页面转向,处理认证的过程是需要authenticationManager
在后台完成,authenticationManager是认证管理器 -->
<property name="authenticationManager" ref="authenticationManager" />

<!-- 认证失败时候转向的页面 -->
<property name="authenticationFailureUrl" value="/login.jsp?error=true" />

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

<!-- 与login.jsp中form的action是一样的,当该表单提交后,authenticationProcessingFilter将从请求中提取出j_username,j_paassword的值
两者组成了代表请求认证的用户信息,acegi将这个信息构造成Authentication实例,并且封装成SecurityContext放入到SecurityContextHolder中
然后启动用户身份认证的流程,如果失败,会/login.jsp?error=true,成功的话.... -->
<property name="filterProcessesUrl" value="/j_security_check" />

<!-- 添加rememberMe,在处理用户登录页面提交的用户认证信息时候,将用户名和密码通过response的方式记录到客户端cookie中
当authenticationProcessingFilter 完成用户认证的时候,如果认证成功,调用 rememberMeServices的loginSuccess()方法
该方法将用户名和密码按以某种方式进行编码,然后再写入到cookie里面 -->
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>

<bean id="securityContextHolderAwareRequestFilter"
class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />

<!-- 自动登录功能,如果保存到cookie里面5天内,再次自动登录。必须有一个过滤器能够自动调用RememberMeServices#autoLogin()方法
这个需要通过rememberMeProcessingFilter过滤器来完成。 -->
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>

<!-- 匿名用户处理过滤器 添加anonymousProcessingFilter到过滤器链中AnonymousProcessingFilter和AnonymousAuthenticationProvider
都拥有一个key属性,key是建立两者联系的桥梁,要想等这样,后者就可以通过key访问到前者创建的AnonymousAuthenticationToken -->
<bean id="anonymousProcessingFilter"
class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="anonymous" />
<!--匿名用户的属性,其中第一项anonymous表示用户密码,第二项ROLE_ANONYMOUS表示对应权限,以逗号分开可以添加多个权限 -->
<property name="userAttribute" value="anonymous,ROLE_ANONYMOUS" />
</bean>

<!-- 异常转换过滤器: 能够扑捉Acegi抛出的权限访问异常,并导向合适相应页面
注意:ExceptionTranslationFilter必须位于FilterSecurityInterceptor之前
-->
<bean id="exceptionTranslationFilter"
class="org.acegisecurity.ui.ExceptionTranslationFilter">
<!-- 通过AuthenticationProcessingFilterEntryPoint定义用户登录页面的地址,在抛出AuthenticationException异常时,
请求到login.jsp页面 -->
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp" />
<property name="forceHttps" value="false" />
</bean>
</property>
</bean>

<!-- start:overrided by bguo since in our project, the authority data is from DB -->
<!--
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource" >
<value>
PATTERN_TYPE_APACHE_ANT
/clickstreams.jsp*=admin
/flushCache.*=admin
/mainMenu.action*=ROLE_ANONYMOUS,admin,user
/passwordHint.action*=ROLE_ANONYMOUS,admin,user
/reload.*=admin
/signup.action*=ROLE_ANONYMOUS,admin,user
/users.action*=admin
/**/*.action*=admin,user
</value>
</property>
</bean>
-->

<!-- URL 资源访问拦截器,添加到拦截器链中,改拦截器将对所有URL请求进行处理,拦截流程如下:
1:判断用户是否已经通过认证,如NO,调用身份认证管理器进行处理,这意味着请求将重定向到登录页面
2:如果通过认证,调用访问决策管理器判断用户是否有权限访问目标 URL资源。
3:访问管理器将组织投票者进行投票,并根据投票结果给出是否有权限访问。
4:如果无权限,则抛出Expception,否则开发URL访问
-->
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<!-- 有上面注释可以得出:FilterSecurityInterceptor要能正常工作,必须得到身份认证管理器和访问决策管理器两者配合 -->
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />

<!-- Authentication#getAuthorities()方法返回的GrantedAuthority[]代表用户的权限信息,但在判断用户是否拥有访问目标URL
权限时候,必须将URL资源事先转换为投票者可以识别的权限信息。改项目通过自己的方法 找出权限信息 -->
<property name="objectDefinitionSource" ref="gbUrlFilterDefinitionSource">
</property>
</bean>
<!-- 上面调用该方法 -->
<bean id="gbUrlFilterDefinitionSource"
class="com.abeam.nasa.service.impl.common.GbUrlDefinitionSource">
<property name="functionDao" ref="functionDao" />
<property name="functionsByUserCache" ref="functionsUserCache" />
<property name="authorityFunctionCache" ref="authorityFunctionCache" />
</bean>

<!-- end:overrided by bguo since in our project, the authority data is from DB -->

<!-- HTTP请求访问决策管理器 -->
<bean id="accessDecisionManager"
class="org.acegisecurity.vote.AffirmativeBased">

<!-- 是否所有投票者弃权 即 为同意 -->
<property name="allowIfAllAbstainDecisions" value="false" />

<!-- 投票者列表 -->
<property name="decisionVoters">
<list>
<!-- 投票者 -->
<bean class="org.acegisecurity.vote.RoleVoter">
<!-- 对应的权限前缀(只对前缀匹配的权限投票) -->
<property name="rolePrefix" value="" />
</bean>
</list>
</property>
</bean>

<!-- RememberMeServices接口实现类TokenBasedRememberMeServices(基于凭证 即:用户名和密码 的remember—me实现类。)
改实现类和logoutFilter的那个TokenBasedRememberMeServices名字一样,但意思相同 可能都实现了。
本项目自己实现了RememberMeServices 并且继承了TokenBasedRememberMeServices实现类。扩展了
-->
<bean id="rememberMeServices"
class="com.abeam.nasa.security.NasaTokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDao" /> <!-- 要引用的Dao -->
<property name="key" value="appfuseRocks" /><!-- Cookie 中的键值,通过key值,可以有效防止整个加密串被黑客改动,因为key值在服务器端 -->
<property name="parameter" value="rememberMe" />
<!-- 也可以添加cookie的有效时间,单位是秒。
<property name="tokenValiditySeconds" value="432000"/>
-->
</bean>

<!--authenticationManager有两个实现类:MockAuthenticationManager和ProviderManager
MockAuthenticationManager用于开发测试环境,它将所有待认证用户标志为有效用户
ProviderManager:将用户的省份认证工作委托给多个提供者来完成。本项目用地是ProviderManager -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<!-- 这里只是加上了3个认证提供者,还有一些其他的.... -->
<!-- 使用基于Dao的认证,转下面的引用 -->
<ref local="daoAuthenticationProvider" />

<!-- 需要将anonymousAuthenticationProvider添加到authenticationManager的认证提供者列表中,以便
AnonymousAuthenticationToken能够通过认证管理器的认证 -->
<ref local="anonymousAuthenticationProvider" />

<ref local="rememberMeAuthenticationProvider" />
</list>
</property>
</bean>
<!-- DaoAuthenticationProvider 首先从SecurityContextHolder的Authentication中得到待认证的用户名,并根据该用户名获取保存在
数据库或其他媒介中真正的系统用户UserDetail对象,紧接着比较Authentication和UserDetails的匹配关系(如看密码是否相同,校验码等),如不匹配失败
本项目用到了自己的认证方式,NasaDaoAuthenticationProvider是自己写的实现UserDetailsServics.没有用到acegi里面的JdbcDaoImpl
和InMemoryDaoImpl。如下:
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
1:这个方式是基于数据库存储的用户信息获取,JdbcDaoImpl是acegi里面UserDetailsServics的实现类。
<bean id="userDetailsService"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" /> //数据源.
<property name="usersByUsernameQuery">
<value>
SELECT username,password,1 FROM t_user WHERE status='1'
AND username = ? //这里的value就是根据用户名来查的值的sql
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
SELECT u.username,p.priv_name FROM t_user u,t_user_priv
p WHERE u.user_id =p.user_id AND u.username = ? //根据用户名来查询用户权限记录的sql
</value>
</property>
</bean>
2:这个方式是基于缓存中的用户信息获取,InMemoryDaoImpl是acegi里面对UserDetailsServics接口的实现类。从内存中获取信息
<bean id="userDetailsService"
class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">

<property name="userMap" > //user权限集合
<value> //用户信息
join=join,PRIV_COMMON,PRIV_1
tom=tom,PRIV_COMMON,PRIV_1,PRIV_2
peter=peter,disable,PRIV_COMMON,PRIV_1
</value>
</property>

或者如下写入properties
<property name="userProperties" > //user权限集合
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="/WEB-INF/users.properties"/>
</bean>
</property>

</bean>
-->
<bean id="daoAuthenticationProvider"
class="com.abeam.nasa.security.NasaDaoAuthenticationProvider">
<property name="userDetailsService" ref="userDao" />
<!-- 加密方式,将页面传来的明文加密然后对比数据库中的 -->
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
<!-- replaced by bguo for LDAP configure start
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDao" />
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
end -->

<!-- 该key与anonymousProcessingFilter的key值要相等-->
<bean id="anonymousAuthenticationProvider"
class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="anonymous" />
</bean>

<bean id="rememberMeAuthenticationProvider"
class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="appfuseRocks" />
</bean>

<!-- This bean definition must be available to ApplicationContext.getBean() so StartupListener
can look for it and detect if password encryption is turned on or not -->
<bean id="passwordEncoder"
class="org.acegisecurity.providers.encoding.ShaPasswordEncoder" />

<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<bean id="loggerListener"
class="org.acegisecurity.event.authentication.LoggerListener" />

<!-- Apply method-level interceptor to userManager bean -->
<!-- start:removed by bguo since in our project, the method is not the control object -->
<!--
<aop:config>
<aop:advisor id="managerSecurity" advice-ref="methodSecurityInterceptor" pointcut="execution(* com.abeam.nasa.service.UserManager.*(..))"/>
</aop:config>

<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
com.abeam.nasa.service.UserManager.getUsers=admin
com.abeam.nasa.service.UserManager.removeUser=admin
</value>
</property>
</bean>
-->
<!-- end:removed by bguo since in our project, the method is not the control object -->

<!-- SSL Switching: to use this, configure it in the filterChainProxy bean -->
<!-- 安全通道过滤器:通过channelProcessiongFilter 对所有URL资源访问进行过滤,当发现访问目标URL所使用的传输协议不符合要求时候,就执行
切换传输协议的操作,该过滤器必须要在过滤器链的最前面。 -->
<bean id="channelProcessingFilter"
class="org.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager"
ref="channelDecisionManager" />
<property name="filterInvocationDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/admin/**=REQUIRES_SECURE_CHANNEL
/login*=REQUIRES_SECURE_CHANNEL
/j_security_check*=REQUIRES_SECURE_CHANNEL
/editProfile.action*=REQUIRES_SECURE_CHANNEL
/signup.action*=REQUIRES_SECURE_CHANNEL
/saveUser.action*=REQUIRES_SECURE_CHANNEL
/**=REQUIRES_INSECURE_CHANNEL
</value>
</property>
</bean>
<!-- ChannelProcessingFilter 过滤器在拦截URL访问的请求后,根据ChannelDesisionManager判断目标URL需要使用的传输协议和当前使用的
协议是否一致,如果不一致,ChannelDecisionManager通过channelProecssors属性定义的通道处理器进行切换 -->
<bean id="channelDecisionManager"
class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<bean
class="org.acegisecurity.securechannel.SecureChannelProcessor" /><!-- 安全通道处理器 -->
<bean
class="org.acegisecurity.securechannel.InsecureChannelProcessor" /><!-- 非安全通道处理器 -->
</list>
</property>
</bean>
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值