如何在Spring中集成Acegi 1.x安全框架

关键字: spring, acegi

    Acegi Security是一个能为基于Spring的企业应用提供强大而灵活安全访问控制解决方案的框架,Acegi已经成为Spring官方的一个子项目,所以也称为Spring Security。它通过在Spring容器中配置一组Bean,充分利用Spring的IoC和AOP功能,提供声明式安全访问控制的功能。
    下面将详细介绍Acegi在Spring中如何配置,配置范例是在acegi-security-1.0.6版本下测试通过的。


1、在web.xml中的配置
Xml代码 复制代码
  1. <!-- 声明Spring Bean的配置文件列表 -->  
  2. <context-param>  
  3.     <param-name>contextConfigLocation</param-name>  
  4.     <param-value>  
  5.         /WEB-INF/config/applicationContext.xml,   
  6.         /WEB-INF/config/ beans-acegi.xml   
  7.     </param-value>  
  8. </context-param>  
  9.   
  10. <!-- 声明Acegi过滤器 -->  
  11. <filter>  
  12.     <filter-name>securityFilter</filter-name>      
  13.     <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>      
  14.     <init-param>      
  15.         <param-name>targetClass</param-name>      
  16.         <param-value>org.acegisecurity.util.FilterChainProxy</param-value>      
  17.     </init-param>      
  18. </filter>  
  19.   
  20. <filter-mapping>  
  21.     <filter-name>securityFilter</filter-name>  
  22.         <url-pattern>/j_security_check</url-pattern>  
  23.     </filter-mapping>  
  24. <filter-mapping>  
  25.     <filter-name>securityFilter</filter-name>      
  26.     <url-pattern>/*</url-pattern>      
  27. </filter-mapping>  
  28.        
  29. 说明:   
  30.     1)安全框架会对/j_security_check和所有的请求进行权限控制。   
  31.     2)Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,以便简化web.xml的配置,并且可以充分利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。  


2、filterChainProxy的配置
Xml代码 复制代码
  1. <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">  
  2.     <property name="filterInvocationDefinitionSource">  
  3.         <value>  
  4.             CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON   
  5.             PATTERN_TYPE_APACHE_ANT   
  6.             /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor</value>      
  7.     </property>  
  8. </bean>  
  9. 说明:   
  10.     1)  过滤器列表必须位于同一行内,中间不能换行。这些过滤器将按顺序被调用。   
  11.     2)  CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON:表示URL比较前先转为小写。   
  12.     3)  PATTERN_TYPE_APACHE_ANT:表示使用Apache Ant的匹配模式  


3、httpSessionContextIntegrationFilter的配置
Xml代码 复制代码
  1. <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>  
  2. 说明:   
  3.     1)  必须将该Filter配置为过滤器链中第一个过滤器,使验证信息能跨越多个请求。   
  4.     2)  为了解决认证主体安全信息能在多个Http请求之间保持共享,Acegi将认证主体安全信息缓存于HttpSession中,当用户请求一个受限的资源时,Acegi通过HttpSessionContextIntegrationFilter将认证主体信息从HttpSession中加载到SecurityContext实例中,认证主体关联的SecurityContext实例则保存在Acegi容器级的SecurityContextHolder里。当请求结束之后,HttpSessionContextIntegrationFilter执行相反的操作,将SecurityContext中的认证主体安全信息重新转存到HttpSession中,然后从SecurityContextHolder中清除对应的SecurityContext实例。   
  5.     3)  SecurityContextHolder是框架级的容器,它保存着和所有用户关联SecurityContext实例,SecurityContext承载着用户的帐号及权限信息,通过以下方法可以取到这些信息:SecurityContextHolder.getContext().getAuthentication()。  


4、logoutFilter的配置
Xml代码 复制代码
  1.     <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">  
  2.         <constructor-arg value="/index.jsp"/>  
  3.         <constructor-arg>  
  4.             <list>  
  5.                 <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>  
  6.             </list>  
  7.         </constructor-arg>  
  8.         <property name="filterProcessesUrl" value="/j_acegi_logout"/>  
  9.     </bean>  
  10.     说明:   
  11.         1)负责处理退出系统后所需要的清理工作。   
  12.         2)  LogoutFilter过滤器的构造方法有两个参数:   
  13. 一个表示成功退出系统后转向的URL;   
  14. 另一个表示退出系统前需要执行的操作,执行的操作可以有多个。   
  15.         3)  SecurityContextLogoutHandler操作类会把HttpSession销毁,清除SecurityContextHolder里的SecurityContext实例,把rememberMeServices从cookies中清除。然后重定向到指定的退出登录页面。   
  16.         4)  filterProcessesUrl:指定用于响应退出系统请求的URL,其默认值为 /j_acegi_logout。当访问的URL为filterProcessesUrl属性值时,logoutFilter过滤器将会被调用。  


5、认证处理过滤器authenticationProcessingFilter的配置
Xml代码 复制代码
  1. <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">  
  2.     <property name="filterProcessesUrl" value="/j_security_check"/>  
  3.     <property name="authenticationFailureUrl" value="/index.jsp?login_error=1"/>  
  4.     <property name="defaultTargetUrl" value="/main.action"/>  
  5.     <property name="authenticationManager" ref="authenticationManager"/>  
  6.     <property name="rememberMeServices" ref=""/><!-可选 -->  
  7. </bean>  
  8. 说明:   
  9.     1)负责处理基于表单的身份验证请求。   
  10.     2)当接收到与filterProcessesUrl所定义相同的请求时,它会首先通过AuthenticationManager来验证用户身份。如果验证成功,则重定向到defaultTargetUrl所定义的成功登陆页面。如果验证失败,则再从 rememberMeServices中获取用户身份。若再获取失败,则重定向到auhenticationFailureUrl所定义的登陆失败页面。   
  11.     3)filterProcessesUrl:默认值为/j_acegi_security_check。该值必须与登录页面form的action值一致。   
  12.    form中输入用户名的input控件的name必须为j_username;输入密码的input控件的name必须为j_password。   
  13.     4)rememberMeServices 负责通过以cookie的形式保存先前的用户登录信息。在Authentication对象不存在时, rememberMeProcessingFilter会调用rememberMeServices的autoLogin()方法,尝试在cookies 中获取用户登录信息,如果存在则返回Authentication对象。在每次用户登录时,如果设置了RememberMe功能,在验证用户身份成功后,则会调用loginSuccess()方法记录用户信息在cookies中,否则调用loginFail()方法清除cookie。  


6、认证管理器authenticationManager的配置
Xml代码 复制代码
  1. <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">  
  2.     <property name="providers">  
  3.         <list>  
  4.             <ref local="daoAuthenticationProvider"/>  
  5.             <ref local="anonymousAuthenticationProvider"/>  
  6.         </list>  
  7.     </property>  
  8. </bean>  
  9. 说明:   
  10.     1)认证管理器用来管理身份验证提供者。它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。   
  11.     2)无论成功与否,认证管理器都会发布一个ApplicationEvent事件对象。  


7、身份验证提供者的配置
Xml代码 复制代码
  1. <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">  
  2.     <property name="userDetailsService" ref="userDao"/>  
  3.     <property name="userCache" ref="userCache"/>  
  4.     <property name="passwordEncoder" ref="passwordEncoder"/><!-可选 -->  
  5. </bean>  
  6. <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">  
  7.     <property name="key" value="anonymous"/>  
  8. </bean>  
  9.   
  10. <bean id="userDao" class="com.cjm.web.dao.impl.UserDaoImpl">  
  11.     <property name="sessionFactory" ref="sessionFactory"/>  
  12. </bean>  
  13.   
  14. <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">  
  15.     <property name="cache">  
  16.         <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">  
  17.             <property name="cacheManager">  
  18.                 <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>  
  19.             </property>  
  20.             <property name="cacheName" value="userCache"/>  
  21.         </bean>  
  22.     </property>  
  23. </bean>  
  24.   
  25. <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>  
  26. 说明:   
  27.     1)daoAuthenticationProvider:负责提供用户信息,包括用户名和密码。其中取用户名密码的工作交给userDetailsService来做。   
  28.     2)anonymousAuthenticationProvider:匿名用户身份验证。   
  29.     3)userDao:用于在数据库中获取用户信息。UserDaoImpl需要实现Acegi提供的UserDetailsService接口类。   
  30.     4)userCache:缓存用户和资源相对应的权限信息。每当请求一个受保护资源时,daoAuthenticationProvider就会被调用以获取用户授权信息。如果每次都从数据库获取的话,那代价很高,对于不常改变的用户和资源信息来说,最好是把相关授权信息缓存起来。   
  31.     5)passwordEncoder:使用加密器对用户输入的明文进行加密。Acegi提供了三种加密器:   
  32.         PlaintextPasswordEncoder---默认,不加密,返回明文   
  33.         ShaPasswordEncoder---哈希算法(SHA)加密   
  34.         d5PasswordEncoder---消息摘要(MD5)加密  


8、securityContextHolderAwareRequestFilter的配置
Xml代码 复制代码
  1. <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>  
  2. 说明:   
  3.     1)负责通过Decorate Model(装饰模式)装饰HttpServletRequest对象。   
  4. Wapper是ServletRequest包装类 HttpServletRequestWrapper的子类(SavedRequestAwareWrapper或者 SecurityContextHolderAwareRequestWrapper)。附上获取用户权限信息,request参数,header, Date,headers和cookies的方法。  


9、anonymousProcessingFilter的配置
Xml代码 复制代码
  1. <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">  
  2.     <property name="key" value="anonymous"/>  
  3.     <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/>  
  4. </bean>  
  5. 说明:         1)该过滤器用于判断ContextHolder中是否有Authentication对象,如果没有就创建一个Authentication对象,其中包含的用户名是anonymous,用户权限是ROLE_ANONYMOUS。这使得没有登录的匿名用户能够自动的获得匿名的用户名和权限。  


10、exceptionTranslationFilter的配置
Xml代码 复制代码
  1.     <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">  
  2.         <property name="authenticationEntryPoint">  
  3.             <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">  
  4.                 <property name="loginFormUrl" value="/index.jsp"/>  
  5.                 <property name="forceHttps" value="false"/>  
  6.             </bean>  
  7.         </property>  
  8.         <property name="accessDeniedHandler">  
  9.             <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">  
  10.                 <property name="errorPage" value="/accessDenied.jsp" />  
  11.             </bean>  
  12.         </property>  
  13.     </bean>  
  14.     说明:   
  15.         1)  该过滤器用于处理身份验证和授权过程中的异常情况。   
  16.         2)  authenticationEntryPoint:将用户重定向到一个基于HTML表单的登录页面。   
  17. loginFormUrl:指定登录页面。   
  18. forceHttps:指定是否强制使用HTTPS协议。   
  19.         3)errorPage:指定访问拒绝时要跳转到的页面。  


11、filterInvocationInterceptor的配置
Xml代码 复制代码
  1.     <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">  
  2.         <property name="authenticationManager" ref="authenticationManager"/>  
  3.         <property name="accessDecisionManager" ref="accessDecisionManager"/>  
  4.         <property name="objectDefinitionSource">  
  5.             <value>  
  6.                 PATTERN_TYPE_APACHE_ANT   
  7.                 /index.jsp*=ROLE_ANONYMOUS   
  8.                 /accessDenied.jsp*=ROLE_ANONYMOUS   
  9. /**/*.jsp*=ADMIN,SYS_MANAGER   
  10.                 /**/*.htm*=ADMIN,SYS_MANAGER   
  11.                 /**/*.action*=ADMIN,SYS_MANAGER   
  12.             </value>  
  13.         </property>  
  14.     </bean>  
  15.     说明:   
  16.     1)该Filter 会首先调用AuthenticationManager判断用户是否已登陆认证,如还没认证成功,则重定向到登陆界面。如认证成功,则从 Authentication中获取用户的权限。然后从objectDefinitionSource属性获取各种URL资源所对应的权限。最后调用 AccessDecisionManager来判断用户所拥有的权限与当前受保护的URL资源所对应的权限是否相匹配。如果匹配失败,则返回403错误给用户。如果匹配成功,则用户可以访问受保护的URL资源。  


12、访问决策管理器accessDecisionManager的配置
Xml代码 复制代码
  1. <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">  
  2.     <property name="allowIfAllAbstainDecisions" value="false"/>  
  3.     <property name="decisionVoters">  
  4.         <list>  
  5.             <bean class="org.acegisecurity.vote.RoleVoter">  
  6.                 <property name="rolePrefix" value=""/>  
  7.             </bean>  
  8.         </list>  
  9.     </property>  
  10. </bean>  
  11. 说明:   
  12.     1)通过投票机制来决定是否可以访问某一资源。Acegi提供三种投票通过策略的实现:   
  13.         AffirmativeBased(至少一个投票者同意方可通过)   
  14.         ConsensusBased(多数投票者同意方可通过)   
  15.         UnanimousBased(所有投票者同意方可通过)   
  16.     2)allowIfAllAbstainDecisions:设定是否允许 "没人反对就通过" 的投票策略。   
  17.     3)  rolePrefix:角色投票者支持的权限前缀,默认为ROLE_。权限必须以rolePrefix设定的值开头才能进行投票。  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值