CAS集群部署基于Redis缓存配置详细方案

21 篇文章 1 订阅
16 篇文章 0 订阅

        CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的、开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(属于 Web SSO )。CAS集群部署首先需要考虑的是ticket票据统一存储的问题,以便于达到每个节点访问的一致性,官方虽然提供了基于memcached方式,但未提供基于Redis方式,项目中需要使用redis,因此仿照memcached方式,新建cas-server-integration-redis工程,来完成工作需求,下面本站素文宅www.yoodb.com就分享一下CAS集群部署基于Redis缓存配置,仅供大家参考学习。


主要特性,具体如下:

1)开源的、多协议的 SSO 解决方案; Protocols : Custom Protocol 、 CAS 、 OAuth 、 OpenID 、 RESTful API 、 SAML1.1 、 SAML2.0 等。

2)支持多种认证机制: Active Directory 、 JAAS 、 JDBC 、 LDAP 、 X.509 Certificates 等;

3)安全策略:使用票据( Ticket )来实现支持的认证协议;

4)支持授权:可以决定哪些服务可以请求和验证服务票据( Service Ticket );

5) 提 供高可用性:通过把认证过的状态数据存储在 TicketRegistry 组件中,这些组件有很多支持分布式环境的实现, 如: BerkleyDB 、 Default 、 EhcacheTicketRegistry 、 JDBCTicketRegistry 、 JBOSS TreeCache 、 JpaTicketRegistry 、 MemcacheTicketRegistry 等;

6)支持多种客户端: Java 、 .Net 、 PHP 、 Perl 、 Apache, uPortal 等。


1、构建cas-server-integration-redis工程

仿照cas-server-integration-memcached工程建立cas-server-integration-redis工程,pom.xml中添加redis的java客户端jar包,去掉memcached中需要的jar,最后依赖包如下:

<!-- ~ Licensed to Jasig under one or  more  contributor license ~ agreements. 
See the NOTICE  file  distributed with this work ~  for  additional information 
regarding copyright ownership. ~ Jasig licenses this  file  to you under the 
Apache License, ~ Version 2.0 (the  "License" ); you may not use this  file 
~ except  in  compliance with the License. You may obtain a ~ copy of the License 
at the following location: ~ ~ http: //www .apache.org /licenses/LICENSE-2 .0 
~ ~ Unless required by applicable law or agreed to  in  writing, ~ software 
distributed under the License is distributed on an ~  "AS IS"  BASIS, WITHOUT 
WARRANTIES OR CONDITIONS OF ANY ~ KIND, either express or implied. See the 
License  for  the ~ specific language governing permissions and limitations 
~ under the License. -->
<project xmlns= "http://maven.apache.org/POM/4.0.0"  xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" >
<parent>
<groupId>org.jasig.cas< /groupId >
<artifactId>cas-server< /artifactId >
<version>3.5.2< /version >
< /parent >
<modelVersion>4.0.0< /modelVersion >
<groupId>org.jasig.cas< /groupId >
<artifactId>cas-server-integration-redis< /artifactId >
<packaging>jar< /packaging >
<name>Jasig CAS Redis Integration< /name >
<dependencies>
<dependency>
<groupId>org.jasig.cas< /groupId >
<artifactId>cas-server-core< /artifactId >
<version>${project.version}< /version >
< /dependency >
<dependency>
<groupId>redis.clients< /groupId >
<artifactId>jedis< /artifactId >
<version>2.8.1< /version >
< /dependency > <!-- Test dependencies -->
<dependency>
     <groupId>org.springframework.data< /groupId >
     <artifactId>spring-data-redis< /artifactId >
     <version>1.7.1.RELEASE< /version >
< /dependency >
<dependency>
<groupId>org.mockito< /groupId >
<artifactId>mockito-core< /artifactId >
<version>1.9.0< /version >
<scope> test < /scope >
< /dependency >
< /dependencies >
< /project >

仿照MemCacheTicketRegistry.java类,定义RedisTicketRegistry.java类,此类是核心,它实现了TicketRegistry接口,具体代码如下:

public  class  RedisTicketRegistry  extends  AbstractDistributedTicketRegistry{
     @NotNull
     private  final  RedisTemplate<String,Object> reidsTemplate;
     /**
      * TGT cache entry timeout in seconds.
      */
     @Min ( 0 )
     private  final  int  tgtTimeout;
     /**
      * ST cache entry timeout in seconds.
      */
     @Min ( 0 )
     private  final  int  stTimeout;
     
     public  RedisTicketRegistry(RedisTemplate<String,Object> reidsTemplate, int  tgtTimeout, int  stTimeout){
         this .reidsTemplate=reidsTemplate;
         this .tgtTimeout=tgtTimeout;
         this .stTimeout=stTimeout;
     }
     @Override
     public  void  addTicket(Ticket ticket) {
         logger.debug( "Adding ticket {}" , ticket);
         try  {
             reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);
         catch  ( final  Exception e) {
             logger.error( "Failed adding {}" , ticket, e);
         }
     }
     @Override
     public  Ticket getTicket(String ticketId) {
          try  {
                 final  Ticket t = (Ticket)  this .reidsTemplate.opsForValue().get(ticketId);
                 if  (t !=  null ) {
                     return  getProxiedTicketInstance(t);
                 }
             catch  ( final  Exception e) {
                 logger.error( "Failed fetching {} " , ticketId, e);
             }
             return  null ;
     }
     @Override
     public  boolean  deleteTicket(String ticketId) {
          logger.debug( "Deleting ticket {}" , ticketId);
             try  {
                  this .reidsTemplate.delete(ticketId);
                  return  true ;
             catch  ( final  Exception e) {
                 logger.error( "Failed deleting {}" , ticketId, e);
             }
             return  false ;
     }
     @Override
     public  Collection<Ticket> getTickets() {
          throw  new  UnsupportedOperationException( "GetTickets not supported." );
     }
     @Override
     protected  void  updateTicket(Ticket ticket) {
      logger.debug( "Updating ticket {}" , ticket);
         try  {
               this .reidsTemplate.delete(ticket.getId());
               reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);
         catch  ( final  Exception e) {
             logger.error( "Failed updating {}" , ticket, e);
         }
     }
     @Override
     protected  boolean  needsCallback() {
         // TODO Auto-generated method stub
         return  true ;
     }
    private  int  getTimeout( final  Ticket t) {
         if  (t  instanceof  TicketGrantingTicket) {
             return  this .tgtTimeout;
         else  if  (t  instanceof  ServiceTicket) {
             return  this .stTimeout;
         }
         throw  new  IllegalArgumentException( "Invalid ticket type" );
     }
}


2、整合cas-server-webapp工程

修改cas-server-webapp工程中ticketRegistry.xml文件,替换掉DefaultTicketRegistry,同时注释掉ticketRegistryCleaner相关所有定义,具体如下:

<bean  id = "ticketRegistry"  class= "com.test.cas.ticket.registry.RedisTicketRegistry" >
         <constructor-arg index= "0"  ref= "redisTemplate"  />
         <constructor-arg index= "1"  value= "1800"  />
         <constructor-arg index= "2"  value= "10"  />
     < /bean >
     <bean  id = "poolConfig"  class= "redis.clients.jedis.JedisPoolConfig" >  
         <property name= "maxIdle"  value= "200"  />  
         <property name= "testOnBorrow"  value= "true"  />  
     < /bean >  
       
     <bean  id = "connectionFactory"  class= "org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
         p:host-name= "127.0.0.1"  p:port= "6379"    p:pool-config-ref= "poolConfig" />  <!—host-name 服务端IP-->
     <bean  id = "redisTemplate"  class= "org.springframework.data.redis.core.RedisTemplate"
         p:connection-factory-ref= "connectionFactory" >
     < /bean >

使用Redis作为ticket票据的存储,需要将原来的配置给注释掉否则启动时报错,具体如下:

<!--   <bean  id = "ticketRegistry"  class= "org.jasig.cas.ticket.registry.DefaultTicketRegistry"  /> --> 
<!--Quartz -->
<!-- TICKET REGISTRY CLEANER -->
<!-- <bean  id = "ticketRegistryCleaner"  class= "org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner"  -->
<!-- p:ticketRegistry-ref= "ticketRegistry"  /> -->
<!-- <bean  id = "jobDetailTicketRegistryCleaner"  class= "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"  -->
<!-- p:targetObject-ref= "ticketRegistryCleaner"  -->
<!-- p:targetMethod= "clean"  /> -->
<!-- <bean  id = "triggerJobDetailTicketRegistryCleaner"  class= "org.springframework.scheduling.quartz.SimpleTriggerBean"  -->
<!-- p:jobDetail-ref= "jobDetailTicketRegistryCleaner"  -->
<!-- p:startDelay= "20000"  -->
<!-- p:repeatInterval= "5000000"  /> -->

在POM.xml中添加cas-server-integration-redis模块:

<dependency>
  <groupId>org.jasig.cas< /groupId >
  <artifactId>cas-server-integration-redis< /artifactId >
  <version>${project.version}< /version >
  <scope>compile< /scope >
< /dependency >

此时CAS配置完毕,启动所有相关服务器即可使用,下面说说tomcat session集群同步的问题


3、tomcat session集群同步

  保证多个实例下,session中的状态以及票据存储状态,是一致的,通过网络上查找资料,实现tomcat session集群同步可以采用开源的tomcat-redis-session-manager,git hub地址为:https://github.com/jcoleman/tomcat-redis-session-manager,注意使用的JDK是JDK1.7,服务器使用的是tomcat7

  1)拷贝编译打包之后的tomcat-redis-session-manager-VERSION.jar,jedis-2.7.2.jar,commons-pool2-2.2.jar到tomcat/lib目录下

  2)修改Tomcat context.xml (or the context block of the server.xml if applicable.)

<Valve className= "com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className= "com.orangefunction.tomcat.redissessions.RedisSessionManager"
          host= "127.0.0.1"
          port= "6379"
          database= "0"
          maxInactiveInterval= "1800" />

到此为止,CAS集群部署工作完毕,欢迎大家收藏本站,有什么疑难问题,尽可留言。

http://blog.yoodb.com/yoodb/article/detail/1221

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值