zoukankan      html  css  js  c++  java
  • 使用ACEGI实现权限控制,第一部分

    环境:
     struts2,acegi1.0.6,spring2.5.1,cas3

    一、综述:环境搭建
    1.spring和acegi版本
    spring2.5.6和acegi1.0.6兼容性问题
    会报
    java.lang.NoClassDefFoundError: org/springframework/web/bind/RequestUtils
    不过据说装合适的spring-webmvc这个jar也可以解决问题,没有测试

    1.搭建acegi环境
    web.xml配置,使用acegi的过滤器
    配置web.xml
    <context-param>中包含新配置文件
    <!-- Acegi过滤器 -->
     <filter>
      <filter-name>acegiFilterChain</filter-name>
      <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
      <init-param>
       <param-name>targetClass</param-name>
       <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
      </init-param>
     </filter>

     <!-- Acegi过滤器URL映射 -->
     <filter-mapping>
      <filter-name>acegiFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
     </filter-mapping>

    过滤器要放在struts前面,否则会报错。因为有些操作要acegi中的springmvc处理
    javax.servlet.ServletException: Filter execution threw an exception
     org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:389)
    java.lang.NoClassDefFoundError: org/springframework/web/bind/RequestUtils
     
    配置acegi配置文件,配置认证管理器、投票管理器、过滤器链、配置acegi的log4j日志

    <?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>
     
     <bean id="daoAuthenticationProvider"
      class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
      <property name="userDetailsService" ref="userDetailsService" />
      <property name="userCache" ref="userCache" />
     </bean>
       
     <!-- 基于DAO验证的Ehcache实现 -->
     <bean id="userCache"
      class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
      <property name="cache" ref="userCacheBackend" />
     </bean>
     <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
      <property name="cacheManager" ref="cacheManager" />
      <property name="cacheName">
       <value>userCache</value>
      </property>
     </bean>
     <bean id="cacheManager"
      class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />

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

     <!-- 使用数据库DAO查找用户和角色 -->
     <bean id="userDetailsService" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
      <property name="dataSource" ref="dataSource" />
      <property name="usersByUsernameQuery">
       <value>
              <![CDATA[SELECT u.staffname USERNAME,u.staffpwd PASSWORD,u.STATUS enabled FROM sw_staff u where u.STATUS = 1 AND u.staffname = ?]]>
       </value>
      </property>
      <property name="authoritiesByUsernameQuery">
       <value>
              <![CDATA[SELECT t1.staffid USERNAME,t3.roledec authority FROM sw_staff t1, SW_UserPower t2,sw_Roles t3 WHERE t1.staffid= t2.staffid and t2.roleid= t3.roleid and t1.staffname = ?]]>
       </value>
      </property>
     </bean>

     <!--
      ========================================================================
      决策管理器
      =========================================================================
     -->
     <!-- 至少有一个投票者容许,就可以访问资源 -->
     <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
      <property name="decisionVoters">
       <list>
        <bean class="org.acegisecurity.vote.RoleVoter" />
       </list>
      </property>
      <!-- 所有投票者弃权,不容许访问 -->
      <property name="allowIfAllAbstainDecisions" value="false" />
     </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
       </value>
      </property>
     </bean>

     <!-- 从Session中获得用户信息并放入SecurityContextHolder -->
     <bean id="httpSessionContextIntegrationFilter"
      class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />

     <!-- 用户注销 -->
     <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
      <!-- 注销后默认的跳转页面 -->
      <constructor-arg value="/helloWorld.jsp" />
      <constructor-arg>
       <list>
        <ref bean="rememberMeServices" />
        <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
       </list>
      </constructor-arg>
      <property name="filterProcessesUrl" value="/j_logout.do" />
     </bean>

     <!-- 表单方式验证用户身份 -->
     <bean id="authenticationProcessingFilter"
      class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
      <property name="authenticationManager" ref="authenticationManager" />
      <!-- 登录失败的页面,包含出错信息的登录页面 -->
      <property name="authenticationFailureUrl" value="/login.jsp?login_error=Login%20failed." />
      <!-- 登录后的跳转页面 -->
      <property name="defaultTargetUrl" value="/helloWorld.jsp" />
      <!-- 用户登录的URL -->
      <property name="filterProcessesUrl" value="/j_acegi_security_check" />
      <property name="rememberMeServices" ref="rememberMeServices" />
     </bean>

     <bean id="casProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter">
      <property name="authenticationManager" ref="authenticationManager" />
      <!-- 登录后的跳转页面 -->
      <property name="defaultTargetUrl" value="/helloWorld.jsp" />
      <property name="filterProcessesUrl" value="/j_acegi_cas_security_check" />
      <!-- 认证失败后的跳转页面 -->
      <property name="authenticationFailureUrl" value="/login.jsp?login_error=Login%20failed." />
      <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>
    -->

     <!-- 处理登录异常或权限异常的Filter -->
     <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" />
       是否强制使用https <property name="forceHttps" value="false" /> </bean>
       </property>
      -->
      <!--CAS认证登录时用-->
      <property name="authenticationEntryPoint">
       <bean class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
        <property name="loginUrl"
         value="https://localhost:8443/cas-server-webapp-3.1.1/login" />
        <property name="serviceProperties" ref="serviceProperties" />
       </bean>
      </property>
      <!-- 出现AccessDeniedException时的Handler,无权限异常-->
      <property name="accessDeniedHandler">
       <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
        <property name="errorPage" value="/accessDenied.jsp" />
       </bean>
      </property>
     </bean>

     <bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties">
      <!-- CAS登录后的重定向页面-->
      <property name="service" value="http://localhost:8080/test" />
      <property name="sendRenew" value="false" />
     </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
        /index.jsp=ROLE_LOGIN
        /*action=ROLE_LOGIN
       </value>
      </property>
     </bean>

    说明:
    1、过滤器链:filterChainProxy,有顺序要求
    /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,rememberMeFilter,exceptionFilter,securityInterceptor

    2、rememberMe配置要点
    rememberMeServices使用TokenBasedRememberMeServices,token64编码后放入cookie
    logoutFilter使用rememberMeServices,离开后保存cookie

    rememberMeFilter配置authenticationManager和rememberMeServices
    rememberMeServices的parameter和html表单的Remember Me字段的name一致
    rememberMeServices的key和authenticationManager中的rememberMeAuthenticationProvider的key要一致

    3、使用DaoAuthenticationProvide实现基于数据库的用户认证授权,userDetailsService中可以用注入sql使用数据库实现,文件方式保存用户基本没啥用
     修改usersByUsernameQuery和authoritiesByUsernameQuery注入sql
     使用Ehache提高性能

    4、配置日志
     <!-- 监听认证授权事件,输出日志 -->
        <bean id="authenticationLoggerListener"
      class="org.acegisecurity.event.authentication.LoggerListener" />

     <bean id="authorizationLoggerListener"
      class="org.acegisecurity.event.authorization.LoggerListener" />

    对应的,如果是log4j.xml
    log4j.xml
    <logger name="log4j.logger.org.acegisecurity" additivity="true">
      <level value="DEBUG" />
      <appender-ref ref="LOG.DEBUG" />
    </logger>
    如果是log4j.properties
    log4j.properties
     log4j.logger.org.acegisecurity=DEBUG  


    5.表单认证
    <bean id="authenticationProcessingFilter"
      class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
      <property name="authenticationManager" ref="authenticationManager" />
      <!-- 登录失败的页面,包含出错信息的登录页面 -->
      <property name="authenticationFailureUrl" value="/login.jsp?login_error=Login%20failed." />
      <!-- 登录后的跳转页面 -->
      <property name="defaultTargetUrl" value="/helloWorld.jsp" />
      <!-- 用户登录的URL -->
      <property name="filterProcessesUrl" value="/j_login.do" />
      <property name="rememberMeServices" ref="rememberMeServices" />
     </bean>
     表单中的username和password的name这里为j_username和j_password,acegi的springmvc实现中用
     filterProcessesUrl默认是j_acegi_security_check,可以修改,需要登录页面同步

    6.用户注销
     logoutFilter中filterProcessesUrl默认是j_acegi_logout,只要将退出页面中url设置为j_acegi_logout就可以触发


    7.授权
    accessDecisionManager:事前评估。使用投票表决器。RoleVoter是基于角色的投票表决器。
    这里securityInterceptor使用文件配置,也可以修改为数据库方式实现

    8.使用aop对方法授权

    第二部分:介绍dbms实现鉴权,包括资源过滤和方法过滤,表结构模型

    第三部门:和CAS集成,包括CAS环境搭建,acegi集成CAS

  • 相关阅读:
    第1章:程序设计和C语言(C语言入门)
    倒计时IE6+
    uploadify 使用 详细 说明
    HTTP&#160;错误
    asp.net 向后台提交 html 代码段 包括 <> 标签
    C#使用NLog记录日志
    IE浏览器 location.href 不跳转
    .Net Core 导出Excel
    .net mvc 获取acion 返回类型
    sql sever 执行较大的文件脚本
  • 原文地址:https://www.cnblogs.com/lodestar/p/2303798.html
Copyright © 2011-2022 走看看