Acegi集成CAS

1、acegi内置了对CAS的支持。这里的CAS是3.2。建立CAS server是一个比较简单的事情。CAS server就是一个标准的war文件,把它发布就可以运行。需要做的仅仅是调整登陆和其他一些页面。

2、先了解一下CAS如何实现SSO。
例子:原有系统A和系统B,现在在它们之间做SSO。
很显然,系统A和B都是CAS client。首先是访问系统A,干掉A的登陆页面,在A的入口判断有没有Ticket(票据),如果没有则重定向到CAS server,在CAS server提供Credential(大多数情况就是用户名和密码)。CAS server的作用非常简单:就是来验证用户密码。正确,则发送Ticket。CAS有5种Ticket,分别是TGC(通过cookie发送的 ticket),ST(Service Ticket),PGT,PGTIOU,PT。其中PGT,PGTIOU,PT属于代理ticket,这里不作讨论。

TGC和ST的关系可以打个比方:
我去中央电视塔去玩,结果发现地下还有个海底世界。SSO前我是这么玩的:先去电视塔买张门票,玩完了;再去海底世界买张门票,玩完了。发现真累,两个景点这么近还要买两次门票,就不能搞个通票吗?于是就SSO。于是这样:我先去电视塔,门卫告诉我你不能进去要买票,于是把我送到通票售票处(CAS server)买票(登录),买吧,于是给了我两张票,注意,是两张,一张发到我手里,上面写着仅限电视塔使用(ST);靠,不是通票吗,咋仅限电视塔使用?别急,还有一张票(TGC)通过cookie发送你看不见。人家说了保证没问题,我咋办,这是人家的规矩,那就先去玩吧。出了电视塔我直扑海底世界,
门卫说要海底世界票,不会吧,我买的通票啊,门卫说不着急,又把我送回通票售票处(CAS server),通票售票处(CAS server)一看,发现我有TGC,嘿嘿,这家伙买过票了不用再买(不用再登录),于是换我一张票(ST)上面写着仅限海底世界使用,于是我就拿着这张票又去海底世界了。于是我明白了啥是SSO了,不就是把买票改成换票了吗?
比方完了,最开始的例子也就不往下继续了。需要注意的是系统A和B整合SSO需要把A、B的用户密码集中管理,你说A中我的用户名是张三,B中是李四,SSO能不能帮我自动识别,回答是不行的。 

 

 

二、acegi配置

以一个典型的web访问来说明整个过程
1、用户访问一个受acegi安全保护的页面或业务方法;
2、用户没有登陆的话显然会抛出AuthenticationException
3、配置exceptionTranslationFilter捕获这个异常重定向到CAS server登陆页面

修改applicationContext-acegi-security.xml文件

        < bean id ="exceptionTranslationFilter" class ="org.acegisecurity.ui.ExceptionTranslationFilter" >
            
< property name ="authenticationEntryPoint" >< ref local ="casProcessingFilterEntryPoint" /></ property >
        
</ bean >
        
        
< bean id ="casProcessingFilterEntryPoint" class ="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint" >
            
< property name ="loginUrl" >< value > https://my.company.com/cas/login </ value ></ property >
            
< property name ="serviceProperties" >< ref local ="serviceProperties" /></ property >
        
</ bean >
        
        
< bean id ="serviceProperties" class ="org.acegisecurity.ui.cas.ServiceProperties" >
            
< property name ="service" >< value > https://server.company.com/myapp/j_acegi_cas_security_check </ value ></ property >
            
< property name ="sendRenew" >< value > false </ value ></ property >
        
</ bean >

  配置casProcessingFilter来处理返回ST(和以前的authenticationProcessingFilter比较类似)

    < bean  id ="casProcessingFilter"  class ="org.acegisecurity.ui.cas.CasProcessingFilter" >
        
< property  name ="authenticationManager" >< ref  local ="authenticationManager" /></ property >
        
< property  name ="authenticationFailureUrl" >< value > /casfailed.jsp </ value ></ property >
        
< property  name ="defaultTargetUrl" >< value > / </ value ></ property >
        
< property  name ="filterProcessesUrl" >< value > /j_acegi_cas_security_check </ value ></ property >
    
</ bean >

配置authenticationManager

    < bean  id ="authenticationManager"  class ="org.acegisecurity.providers.ProviderManager" >
      
< property  name ="providers" >
         
< list >
            
< ref  local ="casAuthenticationProvider" />
         
</ list >
      
</ property >
   
</ bean >
   
  
< bean  id ="casAuthenticationProvider"  class ="org.acegisecurity.providers.cas.CasAuthenticationProvider" >
        
< property  name ="casAuthoritiesPopulator" >< ref  local ="casAuthoritiesPopulator" /></ property >
        
< property  name ="casProxyDecider" >< ref  local ="casProxyDecider" /></ property >
        
< property  name ="ticketValidator" >< ref  local ="casProxyTicketValidator" /></ property >
        
< property  name ="statelessTicketCache" >< ref  local ="statelessTicketCache" /></ property >
        
< property  name ="key" >< value > my_password_for_this_auth_provider_only </ value ></ property >
    
</ bean >  

具体作用的是casAuthenticationProvider,casAuthenticationProvider通过 casProxyTicketValidator来校验ST

     < bean  id ="casProxyTicketValidator"  class ="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator" >
        
< property  name ="casValidate" >< value > https://my.company.com/cas/proxyValidate </ value ></ property >
        
< property  name ="serviceProperties" >< ref  local ="serviceProperties" /></ property >
    
</ bean >  

    

 其他 

 

 需要拷贝casclient-3.2和ehcache-1.3.0.jar加入应用的lib中

以下是整个applicationContext-acegi-security.xml

 

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
    - A simple "base bones" Acegi Security configuration.
    -
    - The sample includes the "popular" features that people tend to use.
    - Specifically, form authentication, remember-me, and anonymous processing.
    - Other features aren't setup, as these can be added later by inserting
    - the relevant XML fragments as specified in the Reference Guide.
    -
    - To assist new users, the filters specified in the FilterChainProxy are
    - declared in the application context in the same order. Collaborators
    - required by those filters are placed at the end of the file.
    -
    - $Id: applicationContext-acegi-security.xml,v 1.3 2008/01/09 01:41:14 fdmeng Exp $
-->

<beans>

    
<bean id="filterChainProxy"
        class
="org.acegisecurity.util.FilterChainProxy">
        
<property name="filterInvocationDefinitionSource">
            
<value><![CDATA[
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /js/**=#NONE#
                /css/**=#NONE#
                /images/**=#NONE#
                /**=httpSessionContextIntegrationFilter,casProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            
]]></value>
        
</property>
    
</bean>

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

    
<bean id="logoutFilter"
        class
="org.acegisecurity.ui.logout.LogoutFilter">
        
<constructor-arg value="/index.jsp" />
        
<!-- URL redirected to after logout -->
        
<constructor-arg>
            
<list>
                
<ref bean="rememberMeServices" />
                
<bean
                    
class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
            
</list>
        
</constructor-arg>
    
</bean>

    
<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="/" />
        
<property name="filterProcessesUrl"
            value
="/j_acegi_security_check" />
        
<property name="rememberMeServices" ref="rememberMeServices" />
    
</bean>

    
<bean id="securityContextHolderAwareRequestFilter"
        class
="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />

    
<bean id="rememberMeProcessingFilter"
        class
="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
        
<property name="authenticationManager"
            ref
="authenticationManager" />
        
<property name="rememberMeServices" ref="rememberMeServices" />
    
</bean>

    
<bean id="anonymousProcessingFilter"
        class
="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
        
<property name="key" value="changeThis" />
        
<property name="userAttribute"
            value
="anonymousUser,ROLE_ANONYMOUS" />
    
</bean>
    
<!-- replace to cas login -->
    
<!-- 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 id="exceptionTranslationFilter"
        class
="org.acegisecurity.ui.ExceptionTranslationFilter">
        
<property name="authenticationEntryPoint">
            
<ref local="casProcessingFilterEntryPoint" />
        
</property>
    
</bean>

    
<bean id="casProcessingFilterEntryPoint"
        class
="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
        
<property name="loginUrl">
            
<value>https://EafyYe:8443/cas-server-webapp-3.2.1.1/login</value>
        
</property>
        
<property name="serviceProperties">
            
<ref local="serviceProperties" />
        
</property>
    
</bean>

    
<bean id="serviceProperties"
        class
="org.acegisecurity.ui.cas.ServiceProperties">
        
<property name="service">
            
<value>http://www.163.com</value>
        
</property>
        
<property name="sendRenew">
            
<value>false</value>
        
</property>
    
</bean>

    
<bean id="casProcessingFilter"
        class
="org.acegisecurity.ui.cas.CasProcessingFilter">
        
<property name="authenticationManager">
            
<ref local="authenticationManager" />
        
</property>
        
<property name="authenticationFailureUrl">
            
<value>/casfailed.jsp</value>
        
</property>
        
<property name="defaultTargetUrl">
            
<value>/</value>
        
</property>
        
<property name="filterProcessesUrl">
            
<value>/j_acegi_cas_security_check</value>
        
</property>
    
</bean>

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

    
<bean id="casAuthenticationProvider"
        class
="org.acegisecurity.providers.cas.CasAuthenticationProvider">
        
<property name="casAuthoritiesPopulator">
            
<ref local="casAuthoritiesPopulator" />
        
</property>
        
<property name="casProxyDecider">
            
<ref local="rejectProxyTickets" />
        
</property>
        
<property name="ticketValidator">
            
<ref local="casProxyTicketValidator" />
        
</property>
        
<property name="statelessTicketCache">
            
<ref local="statelessTicketCache" />
        
</property>
        
<property name="key">
            
<value>my_password_for_this_auth_provider_only</value>
        
</property>
    
</bean>

    
<bean id="casAuthoritiesPopulator"
        class
="org.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">
        
<property name="userDetailsService" ref="inMemDaoImpl" />
    
</bean>

    
<bean id="inMemDaoImpl"
        class
="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
        
<property name="userMap">
            
<value>
                admin=password,ROLE_ADMIN
                marissa=koala,ROLE_ADMIN,ROLE_MARISSA,enabled
            
</value>
        
</property>
    
</bean>

    
<bean id="rejectProxyTickets"
        class
="org.acegisecurity.providers.cas.proxy.RejectProxyTickets" />


    
<bean id="casProxyTicketValidator"
        class
="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">
        
<property name="casValidate">
            
<value>https://eafyye:8443/cas-server-webapp-3.2.1.1/serviceValidate</value>
            
<!-- https://my.company.com/cas/proxyValidate -->
        
</property>
        
<property name="serviceProperties">
            
<ref local="serviceProperties" />
        
</property>
    
</bean>

    
<bean id="statelessTicketCache"
        class
="org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
        
<property name="cache" ref="ticketCacheBackend" />
    
</bean>

    
<bean id="ticketCacheBackend"
        class
="org.springframework.cache.ehcache.EhCacheFactoryBean">
        
<property name="cacheManager" ref="cacheManager" />
        
<property name="cacheName" value="ticketCache" />
    
</bean>

    
<bean id="cacheManager"
        class
="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />








    
<bean id="filterInvocationInterceptor"
        class
="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        
<property name="authenticationManager"
            ref
="authenticationManager" />
        
<property name="accessDecisionManager">
            
<bean class="org.acegisecurity.vote.AffirmativeBased">
                
<property name="allowIfAllAbstainDecisions"
                    value
="false" />
                
<property name="decisionVoters">
                    
<list>
                        
<bean class="org.acegisecurity.vote.RoleVoter" />
                        
<bean
                            
class="org.acegisecurity.vote.AuthenticatedVoter" />
                    
</list>
                
</property>
            
</bean>
        
</property>

        
<property name="objectDefinitionSource">
            
<ref bean="rolePermissionService" />
        
</property>

        
<!--
            <property name="objectDefinitionSource">
            <value><![CDATA[
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /secure/extreme/**=ROLE_SUPERVISOR
            /secure/**=IS_AUTHENTICATED_REMEMBERED
            /project/**=IS_AUTHENTICATED_REMEMBERED
            /secretary/**=ROLE_TELLER
            /**=IS_AUTHENTICATED_ANONYMOUSLY
            ]]></value>
            </property>
        
-->
    
</bean>

    
<bean id="rememberMeServices"
        class
="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
        
<property name="userDetailsService" ref="userDetailsService" />
        
<property name="key" value="changeThis" />
    
</bean>

    
<!--
        <bean id="authenticationManager"
        class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
        <list>
        <ref local="daoAuthenticationProvider" />
        <bean
        class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
        <property name="key" value="changeThis" />
        </bean>
        <bean
        class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
        <property name="key" value="changeThis" />
        </bean>
        </list>
        </property>
        <property name="sessionController">
        <ref bean="concurrentSessionController" />
        </property>
        </bean>
    
-->

    
<bean id="concurrentSessionController"
        class
="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
        
<property name="maximumSessions">
            
<value>1</value>
        
</property>
        
<property name="sessionRegistry">
            
<ref local="sessionRegistry" />
        
</property>
    
</bean>

    
<bean id="sessionRegistry"
        class
="org.acegisecurity.concurrent.SessionRegistryImpl" />

    
<bean id="daoAuthenticationProvider"
        class
="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
        
<property name="userDetailsService" ref="userDetailsService" />
    
</bean>

    
<!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
    
<!--
        <bean id="userDetailsService" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
        <property name="userProperties">
        <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="classpath:users.properties"/>
        </bean>
        </property>
        </bean>
    
-->

    
<bean id="userDetailsService"
        class
="org.security.acegi.AcegiJdbcDaoImpl">
        
<property name="dataSource">
            
<ref bean="dataSource" />
        
</property>

        
<property name="usersByUsernameQuery">
            
<value>
                SELECT u.user_id, u.company_id, u.email, u.password,
                u.enabled from role r, user_role ur, user u where
                r.role_id = ur.role_id and ur.user_id = u.user_id and
                email = ? limit 1
            
</value>
        
</property>

        
<property name="authoritiesByUsernameQuery">
            
<value>
                SELECT u.email, r.role_name FROM user_role ur, user u,
                role r WHERE ur.user_id = u.user_id and ur.role_id =
                r.role_id and u.email = ?
            
</value>
        
</property>
    
</bean>

    
<bean id="rolePermissionService"
        class
="org.security.acegi.AcegiJdbcDefinitionSourceImpl">
        
<property name="dataSource">
            
<ref bean="dataSource" />
        
</property>
        
<property name="permissionsQuery">
            
<value>
                SELECT resource_name, role_name FROM resource_role rr,
                resource re, role ro WHERE rr.role_id = ro.role_id and
                rr.resource_id = re.resource_id
            
</value>
        
</property>
        
<property name="convertUrlToLowercaseBeforeComparison"
            value
="false">
        
</property>
        
<property name="resourceExpression"
            value
="PATTERN_TYPE_APACHE_ANT">
        
</property>
    
</bean>

    
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
    
<bean id="loggerListener"
        class
="org.acegisecurity.event.authentication.LoggerListener" />

</beans>

 

参考 集成ACEGI 进行权限控制

      JA-SIG(CAS)学习笔记3

 

 

 

转载于:https://www.cnblogs.com/eafy/archive/2008/08/07/1263155.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值