读书人

Acegi配备(转)

发布时间: 2012-10-21 09:00:07 作者: rapoo

Acegi配置(转)
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
??? <!-- Acegi -->
??? <import resource="classpath:org/springside/bookstoredemo/components/acegi/applicationContext-acegi-security.xml"/>
</beans>
1.3在applicationContext-acegi-security.xml中添加刚才在Web.xml文件中声明的org.acegisecurity.util.FilterChainPrxy:
??? <bean id="filterChainProxy"
??? ??? value="/admin/index.jsp"/>
??? ??? <property name="filterProcessesUrl"
??? ??? ??? ??? value="/j_acegi_security_check"/>
??? ??? <property name="rememberMeServices" ref="rememberMeServices"/>
??? </bean>
这个bean处理一个认证表单,登陆用的表单必须提交用户名和密码这两个参数给这个filter.由用户名和密码构造一个 UsernamePasswordAuthenticationToken,将传给AuthenticationManager的 authenticate方法进行认证处理。该filter默认处理filterProcessesUrl属性指定的URL,认证失败会转到 authenticationFailureUrl,认证成功会转到defaultTargetUrl页面。

1.7顺序添加securityContextHolderAwareRequestFilter
??? <bean id="securityContextHolderAwareRequestFilter"
??? ??? ref="rememberMeServices"/>
??? </bean>
这个bean以cookie的形式来保存认证信息。负责在用户登录后在本地机上记录用户cookies信息,免除下次再次登陆。检查 AuthenticationManager 中是否已存在Authentication对象,如果不存在则会调用RememberMeServices的aotoLogin方法来从cookies中获取Authentication对象。

1.9顺序添加nonymousProcessingFilter
??? <bean id="anonymousProcessingFilter"
??? ??? value="changeThis"/>
??? ??? <property name="userAttribute"
??? ??? ??? ??? value="anonymousUser,ROLE_ANONYMOUS"/>
??? </bean>
这个bean负责为当不存在任何授权信息时,自动为Authentication对象添加userAttribute中定义的匿名用户权限


1.10顺序添加exceptionTranslationFilter
??? <bean id="exceptionTranslationFilter"
??? ??? value="/acegilogin.jsp"/>
??? ??? ??? ??? <property name="forceHttps" value="false"/>
??? ??? ??? </bean>
??? ??? </property>
??? ??? <property name="accessDeniedHandler">
??? ??? ??? <bean
??? ??? ??? ??? ??? value="/accessDenied.jsp"/>
??? ??? ??? </bean>
??? ??? </property>
??? </bean>
这个bean负责处理各种异常,然后重定向到相应的页面中。

1.11顺序添加filterInvocationInterceptor
??? <bean id="filterInvocationInterceptor"
??? ??? ref="userDetailsService"/>
??? ??? <property name="key" value="changeThis"/>
??? </bean>
这个bean负责通过以cookie的形式保存先前的用户登录信息。在Authentication对象不存在时, rememberMeProcessingFilter会调用rememberMeServices的autoLogin()方法,尝试在cookie中获取用户登录信息,如果存在则并返回Authentication对象。在每次用户登录时,如果设置了RememberMe功能,在验证用户身份成功后,则会调用loginSuccess()方法记录用户信息在cookie中,否则调用loginFail()方法清除cookie。

1.13为1.12添加userDetailsService:
??? <bean id="userDetailsService"
??? ??? ref="dataSource"/>
??? ??? <property name="usersByUsernameQuery">
??? ??? ??? <value>
??? ??? ??? ??? select loginid,passwd,1 from ss_users where status='1'
??? ??? ??? ??? and loginid = ?
??? ??? ??? </value>
??? ??? </property>
??? ??? <property name="authoritiesByUsernameQuery">
??? ??? ??? <value>
??? ??? ??? ??? select u.loginid,r.name from ss_users u,ss_roles r,ss_user_role ur
??? ??? ??? ??? where u.id=ur.user_id and r.id=ur.role_id and u.status='1'
??? ??? ??? ??? and u.loginid=?
??? ??? ??? </value>
??? ??? </property>
??? </bean>


1.14为1.11添加authenticationManager:
??? <bean id="authenticationManager"
??? ??? value="changeThis"/>
??? ??? ??? ??? </bean>
??? ??? ??? ??? <bean
??? ??? ??? ??? ??? ??? value="changeThis"/>
??? ??? ??? ??? </bean>
??? ??? ??? </list>
??? ??? </property>
??? </bean>
AuthenticationManager的其中一个实现是ProviderManager,它负责把身份验证的工作委托给一个或多个Provider(认证提供者).
Provider都是实现AuthenticationProvider接口,该接口有两个方法authenticate()和support(). authenticate()方法会尝试验证用户身份,若验证成功则返回一个Authentication对象,否则抛出一个 AuthenticationException.
support()方法会评估当前Authentication对象是否适合这个Provider来进行进一步的处理,而不是指已经通过.
Provir有多个实现.例如daoAuthenticationProvider,anonymousAuthenticationProvider,rememberMeAuthenticationProvider.

1.15添加daoAuthenticationProvide:
??? <bean id="daoAuthenticationProvider"
??? ??? ref="userDetailsService"/>
??? ??? <property name="userCache" ref="userCache"/>
??? ??? <property name="passwordEncoder" ref="passwordEncoder"/>
??? </bean>
daoAuthenticationProvider负责提供用户信息,包括用户名和密码。其中取用户名密码的工作就交给 userDetailsService来做。通过userCache来缓存用户信息,减少查询数据库次数。用passwordEncoder来使用加密密码。userDetailsService的接口实现有jdbcDaoImpl和inMemoryDaoImpl。jdbcDaoImpl通过数据库获取用户名和密码,而inMemoryDaoImpl则只是通过xml定义的方式来获取。
userCache的接口实现有EhCacheBasedUserCache和NullUserCache。NullUserCache实际上就是不进行缓存。EhCacheBasedUserCache是基于ehcache的开源缓存项目来实现的。
passwordEncoder是使用加密器对用户输入的明文进行加密。Acegi提供了三种加密器:
PlaintextPasswordEncoder---默认,不加密,返回明文.
ShaPasswordEncoder---哈希算法(SHA)加密
d5PasswordEncoder---消息摘要(MD5)加密

1.16添加userCache:
??? <bean name="userCache" autowire="byName">
??? ??? ??? ??? <property name="cacheManager" ref="cacheManager"/>
??? ??? ??? ??? <property name="cacheName" value="userCache"/>
??? ??? ??? </bean>
??? ??? </property>
??? </bean>

1.17添加cacheManager:
??? <bean id="cacheManager" value="true"/>
??? ??? <property name="acegiCacheManager" ref="acegiCacheManager"/>
??? </bean>


1.21添加
org.springside.bookstoredemo.components.acegi.domain.Resource;
org.springside.bookstoredemo.components.acegi.domain.Role;
org.springside.bookstoredemo.components.acegi.domain.User;
org.springside.bookstoredemo.components.acegi.resourcedetails.Resourceimport org.springside.bookstoredemo.components.acegi.Constants;
org.springside.bookstoredemo.components.acegi.resourcedetails.ResourceCache;
org.springside.bookstoredemo.components.acegi.cache.AcegiCacheManager;
org.springside.bookstoredemo.components.acegi.resourcedetails.ResourceDetails;
org.springside.bookstoredemo.components.acegi.intercept.web.DBFilterInvocationDefinitionSource.java;
添加
org.springside.bookstoredemo.components.acegi.domain.hbm.Resource.hbm.xml;
org.springside.bookstoredemo.components.acegi.domain.hbm.Role.hbm.xml;
org.springside.bookstoredemo.components.acegi.domain.hbm.Role.hbm.xml;
这几个文件稍稍改下class的映射地址
在dataAccessContext-hibernate.xml中合适地方添加
??? ??? <property name="mappingDirectoryLocations">
??? ??? ??? <list>
??? ??? ??? ??? <value>
??? ??? ??? ??? ??? classpath*:/org/springside/bookstoredemo/components/acegi/domain/hbm/
??? ??? ??? ??? </value>
??? ??? ??? </list>
??? ??? </property>

1.22添加acegiCacheManager
??? <bean id="acegiCacheManager" autowire="byName">
??? ??? <property name="transactionManager" ref="transactionManager"/>
??? ??? <property name="proxyTargetClass" value="true"/>
??? ??? <property name="target">
??? ??? ??? <bean ref="resourceCache"></property>
??? ??? ??? ??? <property name="userCache" ref="userCache"></property>
??? ??? ??? ??? <property name="sessionFactory" ref="sessionFactory"></property>
??? ??? ??? </bean>
??? ??? </property>
??? ??? <property name="transactionAttributes">
??? ??? ??? <props>
??? ??? ??? ??? <prop key="modify*">PROPAGATION_REQUIRED</prop>
??? ??? ??? ??? <prop key="auth*">PROPAGATION_REQUIRED</prop>
??? ??? ??? ??? <prop key="init*">PROPAGATION_REQUIRED,readOnly</prop>
??? ??? ??? ??? <prop key="refresh*">PROPAGATION_REQUIRED,readOnly</prop>
??? ??? ??? ??? <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
??? ??? ??? </props>
??? ??? </property>
??? </bean>

1.23添加resourceCache
??? <!-- 自建一个resourceCache以存放resource对应的role关系 -->
??? <!--
??? ??? resource缓存实际执行对象
??? -->
??? <bean id="resourceCache"
??? ??? ref="cacheManager"/>
??? ??? ??? ??? <property name="cacheName" value="resourceCache"/>
??? ??? ??? </bean>
??? ??? </property>
??? </bean>

1.24添加loggerListener
??? <!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
??? <bean id="loggerListener"
??? ??? />
??? ??? </property>
??? ??? <property name="accessDecisionManager">
??? ??? ??? <ref local="accessDecisionManager" />
??? ??? </property>
??? ??? <property name="runAsManager">
??? ??? ??? <ref local="runAsManager" />
??? ??? </property>
??? ??? <property name="objectDefinitionSource">
??? ??? ??? <value>
??? ??? ??? ??? sample.contact.ContactManager.create=ROLE_USER
??? ??? ??? ??? sample.contact.ContactManager.getAllRecipients=ROLE_ADMIN
??? ??? ??? </value>
??? ??? </property>
??? </bean>
MethodSecurityInterceptor实现了org.aopalliance.intercept.MethodInterceptor接口.在方法被调用之前,拦截器会先调用AuthenticationManager判断用户身份是否已验证,然后从 objectDefinitionSource中获取方法所应用的权限,再调用AccessDecisionManager来匹配用户权限和方法对应的权限.如果用户没有足够权限调用当前方法,则抛出AccessDeniedException是方法不能被调用.调用runAsManager,使在调用方法前动态改变authentication中获取用户权限.
1.30
??? <bean id="autoProxyCreator" value="true" />
??? ??? <property name="interceptorNames">
??? ??? ??? <list>
??? ??? ??? ??? <idref local="securityInterceptor" />
??? ??? ??? </list>
??? ??? </property>
??? ??? <property name="beanNames">
??? ??? ??? <list>
??? ??? ??? ??? <idref bean="userManager"/>
??? ??? ??? ??? <idref bean="roleManager"/>
??? ??? ??? ??? <idref bean="rescManager"/>
??? ??? ??? </list>
??? ??? </property>
??? </bean>
1.31
BeanNameAutoProxyCreator
设置AOP代理的最简单方法就是用Spring的BeanNameAutoProxyCreator.在BeanNameAutoProxyCreator中选出你所需要的interceptor,和列出你所需要保护的Bean.
??? <bean id="accessDecisionManager" />
??? ??? ??? </list>
??? ??? </property>
??? </bean>

读书人网 >软件架构设计

热点推荐