• 学习Acegi应用到实际项目中(1)


    在此,本人声明,我处于菜鸟阶段,文章的内容大部分摘自zhanjia的博客(http://zhanjia.iteye.com/category/43399),旨在学习,有很多地方,我理解不够透彻,可能存在不合理的地方,请大家多担待。

    如需了解关于Acegi的相关内容,请点击:http://www.cnblogs.com/cainiaomahua/p/8806357.html

    一般来说,Acegi的配置主要包括两个方面的内容:web.xml中过滤器的配置和Acegi安全文件的配置。

    一、web.xml中过滤器的配置

    1.  FilterToBeanProxy

    Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这好处是简化了web.xml的配置,并且充分利用了Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。

    <filter>
            <filter-name>Acegi Filter Chain Proxy</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>

    2. filter-mapping
      <filter-mapping>限定了FilterToBeanProxy的URL匹配模式,只有*.do和*.jsp和/j_acegi_security_check (/j_acegi_logout)的请求才会受到权限控制,对javascript,css等不限制。

    <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>*.do</url-pattern>
    </filter-mapping>
    <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>/j_acegi_security_check</url-pattern>
    </filter-mapping>
    <!--
    <filter-mapping>
        <filter-name>Acegi Filter Chain Proxy</filter-name>
        <url-pattern>/j_acegi_logout</url-pattern>
    </filter-mapping>        
    -->

    当然,也可以对所有请求进入权限控制,如下:

    <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>/*</url-pattern>
    </filter-mapping>

    具体配置应根据实际的需求。

    二、Acegi安全文件的配置

    1. 过滤链(FILTER CHAIN)

      FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring ioc的功能, CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转为小写,PATTERN_TYPE_APACHE_ANT定义了使用Apache ant的匹配模式

    <bean id="filterChainProxy"
            class="org.acegisecurity.util.FilterChainProxy">
            <property name="filterInvocationDefinitionSource">
                <value>
                    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                    PATTERN_TYPE_APACHE_ANT
                    /**=httpSessionContextIntegrationFilter,basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
               </value>
           </property>
    </bean>

    2. httpSessionContextIntegrationFilter
      每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须在其他Acegi filter前使用,使之能跨越多个请求。

    <bean id="httpSessionContextIntegrationFilter"
            class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
    </bean>

    3. basicProcessingFilter 
      用于处理HTTP头的认证信息,如从Spring远程协议(如Hessian和Burlap)或普通的浏览器如IE,Navigator的HTTP头中获取用户信息,将他们转交给通过authenticationManager属性装配的认证管理器。如果认证成功,会将一个Authentication对象放到会话中,如果认证失败,会将控制转交给认证入口点(通过authenticationEntryPoint属性装配)

    <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
          <property name="authenticationManager" ref="authenticationManager" />
          <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" />
    </bean>

    4. basicProcessingFilterEntryPoint 
      通过向浏览器发送一个HTTP401(未授权)消息,提示用户登录。
    处理基于HTTP的授权过程, 在当验证过程出现异常后的"去向",通常实现转向、在response里加入error信息等功能。

    <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
              <property name="realmName" value="Acegi First Realm Name" />
    </bean>

    其中,realmName属性取值并不存在太多的实际含义,运行时,”Acegi First Realm Name“字符串会显示在IE浏览器弹出的HTTP BASIC认证对话框中。

    5. exceptionTranslationFilter
      异常转换过滤器,主要是处理AccessDeniedException和AuthenticationException,将给每个异常找到合适的"去向" 

    <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
           <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" />
    </bean>

    在此,如果认证不通过将会将控制转交给认证入口点(通过authenticationEntryPoint属性装配)

    6. authenticationManager
      起到认证管理的作用,它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
    Acegi提供了不同的AuthenticationProvider的实现,如:
            DaoAuthenticationProvider 从数据库中读取用户信息验证身份
            AnonymousAuthenticationProvider 匿名用户身份认证
            RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
            AuthByAdapterProvider 使用容器的适配器验证身份
            CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登陆
            JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证身份
            RemoteAuthenticationProvider 根据远程服务验证用户身份
            RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
            X509AuthenticationProvider 从X509认证中获取用户信息验证身份
            TestingAuthenticationProvider 单元测试时使用

            每个认证者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。

    <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
            <property name="providers">
                <list>
                    <ref local="daoAuthenticationProvider" />
                </list>
            </property>
    </bean>

    7. daoAuthenticationProvider
      进行简单的基于数据库的身份验证。DaoAuthenticationProvider获取数据库中的账号密码并进行匹配,若成功则在通过用户身份的同时返回一个包含授权信息的Authentication对象,否则身份验证失败,抛出一个AuthenticatiionException。

    <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
            <property name="userDetailsService" ref="inMemDaoImpl" />
    </bean>
    <bean id="inMemDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
            <property name="userMap">
                <value>
                    javaee=password,ROLE_SUPERVISOR
                    qiuzj=password,ROLE_SUPERVISOR,disabled
                </value>
            </property>
    </bean>

    inMemDaoImpl提供的是基于内存存储用户的信息,inMemDaoImpl借助于userMap属性定义了若干用户。其中qiuzj状态为disabled,即处于失效状态

    javaee=password,ROLE_SUPERVISOR格式为: 用户名=密码,以逗号分隔的多个角色

    qiuzj =password,ROLE_SUPERVISOR,disabled格式为: 用户名=密码,以逗号分隔的多个角色,用户状态

    8. filterInvocationInterceptor
      在执行转向url前检查objectDefinitionSource中设定的用户权限信息。首先,objectDefinitionSource中定义了访问URL需要的属性信息(这里的属性信息仅仅是标志,告诉accessDecisionManager要用哪些voter来投票)。然后,authenticationManager调用自己的provider来对用户的认证信息进行校验。最后,有投票者根据用户持有认证和访问url需要的属性,调用自己的voter来投票,决定是否允许访问。

    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
            <property name="objectDefinitionSource">
                <value>
                    <![CDATA[
                        CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                        PATTERN_TYPE_APACHE_ANT
                        /secure.jsp=ROLE_SUPERVISOR
                    ]]>
                </value>
           </property>
    </bean>
        

    objectDefinitionSource定义了web资源与角色的对应关系,即URL的权限配置信息。用于指定不同的URL资源对应的权限。例如配置:

    /**/*.jpg=AUTH_ANONYMOUS,AUTH_USER
    /**/*.gif=AUTH_ANONYMOUS,AUTH_USER
    /**/*.png=AUTH_ANONYMOUS,AUTH_USER
    /login.jsp*=AUTH_ANONYMOUS,AUTH_USER
    /**=AUTH_USER

    以上配置指定AUTH_ANONYMOUS权限的用户(即匿名用户)只可以访问图片资源和登录页面,AUTH_USER权限的用户可以访问全部WEB资源。

    9. httpRequestAccessDecisionManager(投票通过策略管理器)用于管理投票通过策略。Acegi提供三种投票通过策略的实现:

    AffirmativeBased(至少一个投票者同意方可通过),ConsensusBased(多数投票者同意方可通过),UnanimousBased(所有投票者同意方可通过)。本程序采用AffirmativeBased策略,并且禁止“没人反对就通过”的投票策略。

    <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
            <property name="allowIfAllAbstainDecisions" value="false"/>
            <property name="decisionVoters">
                <list>
                    <bean class="org.acegisecurity.vote.RoleVoter"/>
                </list>
            </property>
    </bean>

    必须是以rolePrefix设定的value开头的权限才能进行投票,如AUTH_ , ROLE_

    <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
            <property name="rolePrefix" value="AUTH_"/>
    </bean>

    默认时,rolePrefix = "ROLE_"

     

  • 相关阅读:
    cocospods 卡在 Analyzing dependencies
    android px、sp、dp之间的互转
    Android 4.4环境搭建——Android SDK下载与安装
    我心中的核心组件(可插拔的AOP)~大话开篇及目录
    EF架构~AutoMapper对象映射工具简化了实体赋值的过程
    我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器
    EF架构~为EF DbContext生成的实体添加注释(T5模板应用)
    品味编程~底层开发人员应该这样设计一个字体类
    Study notes for Clustering and K-means
    深入理解Oracle索引(25):一招鲜、吃遍天之单字段索引创建思路
  • 原文地址:https://www.cnblogs.com/cainiaomahua/p/8797343.html
Copyright © 2020-2023  润新知