Acegi 配置实例

这里,需要注意以下两点:
1) 这几个filter的顺序是不能更改的,顺序不对将无法正常工作;
2) 如果你的应用不需要安全传输,如https,则将"Acegi Channel Processing Filter"相关内容注释掉即可;
3) 如果你的应用不需要Spring提供的远程访问机制,如Hessian and Burlap,将"Acegi HTTP BASIC Authorization 
Filter"相关内容注释掉即可。

[applicationContext.xml]
接下来就是要添加applicationContext.xml中的内容了,从刚才FilterToBeanFactory的解释可以看出,真正的filter都
在Spring的applicationContext中管理:

1) 首先,你的数据库中必须具有保存用户名和密码的table,Acegi要求table的schema必须如下:

CREATE TABLE users (
    username VARCHAR(50) NOT NULL PRIMARY KEY,
    password VARCHAR(50) NOT NULL,
    enabled BIT NOT NULL
);
CREATE TABLE authorities (
    username VARCHAR(50) NOT NULL,
    authority VARCHAR(50) NOT NULL
);
CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users
(username);

2) 添加访问你的数据库的datasource和Acegi的jdbcDao,如下:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
  <property name="url"><value>${jdbc.url}</value></property>
  <property name="username"><value>${jdbc.username}</value></property>
  <property name="password"><value>${jdbc.password}</value></property>
</bean>
<bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
  <property name="dataSource"><ref bean="dataSource"/></property>
</bean>

<?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">
    
    <!-- 1配置FilterChainProxy -->
    
    <!-- FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring ioc的功能 -->
	<bean id="filterChainProxy"
        class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON   <!-- 定义了url比较前先转为小写-->
                PATTERN_TYPE_APACHE_ANT                      <!-- 定义了使用Apache ant的匹配模式-->
                /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            </value>
        </property>
    </bean>
    
    <!-- 2配置8个filter过滤器 -->
    
     <!--这个bean负责每次请求从HttpSession中获取Authentication对象,然后把Authentication存于一个新的 ContextHolder对象 -->  
    <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
    <!-- 注销处理filter,这个bean负责处理退出登录后所需要的清理工作。它会把session销毁,把ContextHolder清空, 把rememberMeServices从cookies中清除掉,然后重定向到指定的退出登陆页面 --> 
    <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
        <constructor-arg value="/shop/index.do"/>
        <!-- URL redirected to after logout -->
        <constructor-arg>
            <list>
                <ref bean="rememberMeServices"/>
                <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
            </list>
        </constructor-arg>
    </bean>
    <!-- 表单认证处理filter,这个bean处理一个认证表单,登陆用的表单必须提交用户名和密码这两个参数给这个filter.由用户名和密码构造一个 UsernamePasswordAuthenticationToken,将传给AuthenticationManager的 authenticate方法进行认证处理。该filter默认处理filterProcessesUrl属性指定的URL,认证失败会转到 authenticationFailureUrl,认证成功会转到defaultTargetUrl页面。
     --> 
    <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureUrl" value="/acegilogin.jsp?login_error=1"/><!-- 定义登陆失败时转向的页面 -->
        <property name="defaultTargetUrl" value="/admin/index.jsp"/><!-- 义登陆成功时转向的页面 -->
        <property name="filterProcessesUrl"  value="/j_acegi_security_check"/><!-- 定义登陆请求的页面 -->
        <property name="rememberMeServices" ref="rememberMeServices"/><!--用于在验证成功后添加cookie信息-->
    </bean>
    <!--这个bean保存当前的请求到SavedRequest,并存入Session,然后转到登录页。  -->
    <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
    <!-- 这个bean以cookie的形式来保存认证信息。负责在用户登录后在本地机上记录用户cookies信息,免除下次再次登陆。检查 AuthenticationManager 中是否已存在Authentication对象,如果不存在则会调用RememberMeServices的aotoLogin方法来从cookies中获取Authentication对象。 -->
    <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="rememberMeServices" ref="rememberMeServices"/>
    </bean>
    <!-- 这个bean负责为当不存在任何授权信息时,自动为Authentication对象添加userAttribute中定义的匿名用户权限 -->
     <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
        <property name="key" value="changeThis"/>
        <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
    </bean>
    <!-- 异常转换过滤器,主要是处理AccessDeniedException和AuthenticationException,将给每个异常找到合适的"去向"  -->
    <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint">
            <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                <property name="loginFormUrl" value="/acegilogin.jsp"/>
                <property name="forceHttps" value="false"/>
            </bean>
        </property>
        <property name="accessDeniedHandler">
            <bean  class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
                <property name="errorPage" value="/accessDenied.jsp"/>
            </bean>
        </property>
    </bean>
    <!-- 这个bean会首先调用AuthenticationManager判断用户是否已登陆认证,如还没认证成功,则重定向到登陆界面.认证成功,则从 Authentication中获取用户的权限.然后从objectDefinitionSource属性获取各种URL资源所对应的权限.最后调用 AccessDecisionManager来判断用户所拥有的权限与当前受保护的URL资源所对应的权限是否相匹配.如果匹配失败,则返回403错误给用户.匹配成功则用户可以访问受保护的URL资源 -->
    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="objectDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /system/*.jsp*=admin
                /login.jsp*=ROLE_ANONYMOUS,admin,user
                /index.jsp*=ROLE_ANONYMOUS,admin,user
                
            </value>
        </property>
    </bean>
    
    <!-- 3配置rememberMeServices记录cookie-->
    
    <!-- 这个bean负责通过以cookie的形式保存先前的用户登录信息。在Authentication对象不存在时, rememberMeProcessingFilter会调用rememberMeServices的autoLogin()方法,尝试在cookie中获取用户登录信息,如果存在则并返回Authentication对象。在每次用户登录时,如果设置了RememberMe功能,在验证用户身份成功后,则会调用loginSuccess()方法记录用户信息在cookie中,否则调用loginFail()方法清除cookie。 -->
     <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
        <property name="userDetailsService" ref="userJdbcDaoImpl"/>
        <property name="key" value="changeThis"/>
     </bean>
     <!-- 用于在数据中获取用户信息。 acegi提供了用户及授权的表结构,但是您也可以自己来实现。通过usersByUsernameQuery这个SQL得到你的(用户ID,密码,状态信息);通过authoritiesByUsernameQuery这个SQL得到你的(用户ID,授权信息) -->
     <bean id="userJdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
        <property name="dataSource" 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>
     
     <!-- 4配置authenticationManager-->
     
     <!-- AuthenticationManager的其中一个实现是ProviderManager,它负责把身份验证的工作委托给一个或多个Provider(认证提供者). -->
      <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
         <property name="providers">
            <list>
                <ref local="daoAuthenticationProvider"/>
                <ref local="anonymousAuthenticationProvider"/>
                <ref local="rememberMeAuthenticationProvider"/>
            </list>
        </property>
    </bean>   
    <!--
                        通过Providers提供认证者列表,如果一个认证提供者失败可以尝试另外一个认证提供者,以保证获取不同来源的身份认证,如
         DaoAuthenticationProvider 从数据库中读取用户信息验证身份
         AnonymousAuthenticationProvider 匿名用户身份认证
         RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
                       其它的还有
         AuthByAdapterProvider 使用容器的适配器验证身份
         CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登录
         JaasAuthenticationProvider 从JASS登录配置中获取用户信息验证身份
         RemoteAuthenticationProvider 根据远程服务验证用户身份
         RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
         X509AuthenticationProvider 从X509认证中获取用户信息验证身份
         TestingAuthenticationProvider 单元测试时使用
                        每个认证者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。
     -->
    <!-- daoAuthenticationProvider负责提供用户信息,包括用户名和密码。其中取用户名密码的工作就交给 userDetailsService来做。通过userCache来缓存用户信息,减少查询数据库次数。用passwordEncoder来使用加密密码。userDetailsService的接口实现有jdbcDaoImpl和inMemoryDaoImpl。jdbcDaoImpl通过数据库获取用户名和密码,而inMemoryDaoImpl则只是通过xml定义的方式来获取。 -->
     <bean id="daoAuthenticationProvider"
        class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userJdbcDaoImpl"/><!-- 认证数据访问对象,用于获取用户信息,包括:用户名,用户密码,用户状态和用户权限 -->
        <property name="userCache" ref="userCache"/><!-- 缓存user信息 -->
        <property name="passwordEncoder" ref="passwordEncoder"/><!-- 对密码进行私钥加密 -->
    </bean>  
    <!-- userCache提供了两种实现: NullUserCache和EhCacheBasedUserCache, NullUserCache实际上就是不进行任何缓存,EhCacheBasedUserCache是使用Ehcache来实现缓功能 --> 
    <bean name="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
        <property name="cache">
            <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" autowire="byName">
                <property name="cacheManager" ref="cacheManager"/>
                <property name="cacheName" value="userCache"/>
            </bean>
        </property>
    </bean>
     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation">
            <value>classpath:org/springside/bookstoredemo/components/acegi/ehcache.xml</value>
        </property>
    </bean>
    <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>
    <!-- anonymousAuthenticationProvider-->
    <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
        <property name="key" value="anonymous"/>
    </bean>
    <!-- rememberMeAuthenticationProvider-->
    <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
        <property name="key" value="appfuseRocks"/>
    </bean>
   
    <!-- 5配置accessDecisionManager-->
    
    <!-- authenticationManager,AccessDecisionManager来判断用户所拥有的权限与当前受保护的URL资源所对应的权限是否相匹配.如果匹配失败,则返回403错误给用户.匹配成功则用户可以访问受保护的URL资源-->
     <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/><!-- allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过。可选的决策机制有ConsensusBased和UnanimousBased -->
        <property name="decisionVoters">
            <list>
                <bean class="org.acegisecurity.vote.RoleVoter">
                    <property name="rolePrefix" value="AUTH_"/>  <!-- 必须是以rolePrefix设定的value开头的权限才能进行投票,如AUTH_ , ROLE_ -->
                </bean>
            </list>
        </property>
    </bean>
    
    <!-- 5配置authenticationProcessingFilterEntryPoint-->
    
    <!-- 当抛出AccessDeniedException时,将用户重定向到登录界面。属性loginFormUrl配置了一个登录表单的URL,当需要用户登录时,authenticationProcessingFilterEntryPoint会将用户重定向到该URL -->
    <bean id="authenticationProcessingFilterEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
        <property name="loginFormUrl">
		    <value>/security/login.jsp</value>        
		</property>
	    <property name="forceHttps" value="false"/>
	</bean>
	
    <!-- 6配置MethodSecurityInterceptor-->
    
     <!-- MethodSecurityInterceptor实现了org.aopalliance.intercept.MethodInterceptor接口.在方法被调用之前,拦截器会先调用AuthenticationManager判断用户身份是否已验证,然后从 objectDefinitionSource中获取方法所应用的权限,再调用AccessDecisionManager来匹配用户权限和方法对应的权限.如果用户没有足够权限调用当前方法,则抛出AccessDeniedException是方法不能被调用.调用runAsManager,使在调用方法前动态改变authentication中获取用户权限. -->
     <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="objectDefinitionSource">
             <value>
             <!-- 
                  sample.contact.ContactManager.create=ROLE_USER
                  sample.contact.ContactManager.getAllRecipients=ROLE_ADMIN
              -->
             </value>
        </property>
    </bean>

    <!-- 7配置channelProcessingFilter-->
    
    <!-- 如果需要一些页面通过安全通道的话,如https -->
    <bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter">
        <property name="channelDecisionManager" ref="channelDecisionManager"/>
        <property name="filterInvocationDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /admin/**=REQUIRES_SECURE_CHANNEL
                /login*=REQUIRES_SECURE_CHANNEL
                /j_security_check*=REQUIRES_SECURE_CHANNEL
                /editProfile.html*=REQUIRES_SECURE_CHANNEL
                /signup.html*=REQUIRES_SECURE_CHANNEL
                /saveUser.html*=REQUIRES_SECURE_CHANNEL
                /**=REQUIRES_INSECURE_CHANNEL
            </value>
        </property>
    </bean>
    <bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl">
        <property name="channelProcessors">
            <list>
                <bean class="org.acegisecurity.securechannel.SecureChannelProcessor"/>
                <bean class="org.acegisecurity.securechannel.InsecureChannelProcessor"/>
            </list>
        </property>
    </bean>
    
    <!-- 7配置basicProcessingFilter -->
    
    <!-- 如果需要一些页面通过安全通道的话,如https -->
    <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint"/>
    </bean>
     <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">	        
		<property name="realmName" value="SpringSide Realm"/>
	</bean>
    
    
     <!-- 添加loggerListener-->
    <bean id="loggerListener"  class="org.acegisecurity.event.authentication.LoggerListener"/>   
    
    
</beans>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值