Acegi+Spring+Hibernate+Struts2搭建角色权限控制系统

安全永远是WEB应用系统必须面对的头等大事, 也是最头疼的事, 其实安全系统就只包括两个问题: 认证和授权.  以前做些网站系统, 安全检测逻辑都在放在须要安全控制的代码前面, 这样做有很多不好的地方, 重复多次的编码就不用说了, 代码移植性, 重用性都得不到体现, 安全检测逻辑要永远和业务逻辑放在一起.那么, 能不能够在进入方法前就调用一些安全检测? 其实Spring AOP就是这个思想, 那么又如何实现安全检测呢? Spring Acegi Security 框架就是做这个事情.
     本文主要是讨论下在已有的SSH系统中, 如何使用Acegi作为安全框架实现基于角色的权限控制(Role Based Access Control RBAC) , 本文主要是以Java 5注解的形式来配置安全框架, 大大减化配置和操作.
 
    说明: 本文介绍的是RBAC, 在官方文档的基础上有所扩展或改动, 以更适合WEB应用系统. 其实我觉得大多数的网站基于角色已经足够了, 一般都没必要基于权限.
 
一. 下载所要的软件或JAR包:
    我的相关配置是: Java 5, Tomcat 5.5.26, Struts 2.0.11, Spring 2.5.1, Hibernate 3.2, Acegi 1.0.6
二. 建立相关的数据库:
     数据表: 用户信息表User: id, enable, user_name, user_pass, email_box
                 角色信息表RoleInfo: id, role_name, role_title, descp
                 用户与角色关联表(用户与角色是多对多关系)UserRole: user_id, user_name, role_id, role_name
                并在这三个表中插入相关的数据, 我是定义了两种角色(role_name): ROLE_USER, ROLE_ADMIN
                和三个用户, 一个用户角色为: ROLE_USER, ROLE_ADMIN
                 另一个用户角色为: ROLE_USER
                第三个没有角色.
二. 修改配置文件:
    其实对Acegi框架的应用难点就在配置文件, 所以要特别注意了:
    在 src 建立Acegi的配置文件: acegi-security.xml 当然这个文件的名称是可以任意的. acegi-security.xml 说白了就是配置: 安全拦截器, 认证管理器, 决策管理器.
    其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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.xsd">
<!-- ========================= 认证管理器 ========================= -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
   <list>
    <ref bean="daoAuthenticationProvider" />
    <ref bean="rememberMeAuthenticationProvider" />
   </list>
</property>
</bean>
<!-- 基于DAO验证的AuthenticationProvider -->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<bean id="userDetailsService" class="org.ymcn.security.AcegiUserDeitailsService">
<property name="userDao" ref="userDao" />
<property name="userRoleDao" ref="userRoleDao" />
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="[url=mailto:[email protected]][email protected][/url]" />
</bean>
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService" />
<property name="parameter" value="j_remember_me" />
<property name="key" value="[url=mailto:[email protected]][email protected][/url]" />
<property name="tokenValiditySeconds" value="31536000" />
</bean>
<!-- ========================= 决策管理器 ========================= -->
<bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<property name="decisionVoters">
   <list>
    <ref bean="roleVoter" />
   </list>
</property>
<!-- 是否全部弃权就通过 -->
<property name="allowIfAllAbstainDecisions" value="false" />
</bean>
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value="ROLE_" />
</bean>
<!-- ========================= 过滤器链 ========================= -->
<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,rememberMeFilter,exceptionFilter,securityInterceptor   
   </value>
</property>
</bean>
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<!-- 登录退出后的URL -->
<constructor-arg value="/" />
<constructor-arg>
   <list>
    <ref bean="rememberMeServices" />
    <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
   </list>
</constructor-arg>
<!-- 登录退出的URL -->
<property name="filterProcessesUrl" value="/j_logout.j" />
</bean>
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<!-- 登录失败后的URL -->
<property name="authenticationFailureUrl" value="/login.jsp?msg=%E6%97%A0%E6%95%88%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E6%88%96%E5%8F%A3%E4%BB%A4" />
<!-- 登录成功后的URL -->
<property name="defaultTargetUrl" value="/user/cmd.jsp" />
<!-- 登录的URL -->
<property name="filterProcessesUrl" value="/j_login.j" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>
<bean id="rememberMeFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>
<bean id="exceptionFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<!-- 出现AuthenticationException时的登录入口 -->
<property name="authenticationEntryPoint">
   <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
   <property name="loginFormUrl" value="/login.jsp" />
    <property name="forceHttps" value="false" />
   </bean>
</property>
<!-- 出现AccessDeniedException时的Handler -->
<property name="accessDeniedHandler">
   <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
   <property name="errorPage" value="/denied.jsp" />
   </bean>
</property>
</bean>
<bean id="securityInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
   <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    PATTERN_TYPE_APACHE_ANT
    /admin/**=ROLE_ADMIN
    /user/**=ROLE_USER
    /cart/previeworder*=ROLE_USER
   </value>
</property>
</bean>
</beans>
    在上面的配置文件中, 红色部分要特别注意, 其余的内容都差不多了.
<bean id="userDetailsService" class="org.ymcn.security.AcegiUserDeitailsService">
<property name="userDao" ref="userDao" />
<property name="userRoleDao" ref="userRoleDao" />
</bean>
    在整个应用的安全控制中, 我们唯一要编写代码的类就是: org.ymcn.security.AcegiUserDeitailsService
    就连登录和登出的代码也不要了.



本篇文章链接地址:http://www.javaweb.cc/other/code/231059.shtml

猜你喜欢

转载自xxs673076773.iteye.com/blog/1131201