CAS4.0.0鏈接Redis4.0.6

前言

    最近,部門要求爲原有CAS服務配置redis,將CAS的TGT存儲到Redis中,從而提高CAS服務的性能。我上網查詢了許多資料,卻因爲創建JedisPool時出現的BUG,而糾結痛苦了好長時間。己所不欲,勿施於人,我節選了CAS配置文檔中,關於鏈接Redis的部分,分享出來,希望能幫助大家。

2.5.1、版本信息

CAS服務器版本爲4.0.0
Redis數據庫版本爲4.0.6

2.5.2、Redis相關的配置

    Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。它通常被稱爲數據結構服務器,因爲值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。
    本文是基於Java語言的開發,使用Java語言調用Redis的相關服務,需要調用相關jar包——jedis-2.9.0.jar。將該jar包複製到cas服務器工程中,路徑 cas/WEB-INF/lib 下。
    Redis數據庫的安裝略,請自行百度安裝。
    建議安裝一個Redis客戶端——RedisDesktopManager,用來查看數據庫信息。

2.5.3、CAS服務器的改造

2.5.3.1、自定義CAS鏈接Redis類

    在myeclipse中創建Java web工程,工程名隨意。將Redis的連接包jedis-2.9.0.jar 和CAS服務的cas-server-core-4.0.0.jar導入到工程中,cas-server-core-4.0.0.jar在你下載的cas-server-4.0.0-release的 .../cas-server-4.0.0/modules下。
在工程中創建名爲 org.jasig.cas.ticket 的包,在該包下創建名爲RedisTicketRegistry的類,在該類中定義CAS與Redis交互的方法。該類需要繼承CAS自身的抽象類——AbstractDistributedTicketRegistry。代碼如下:
package org.jasig.cas.ticket;


import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.util.Collection;  
  
import org.jasig.cas.ticket.Ticket;  
import org.jasig.cas.ticket.TicketGrantingTicket;  
import org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry;  
  
 
import redis.clients.jedis.Jedis;  
import redis.clients.jedis.JedisPool;  
import redis.clients.jedis.JedisPoolConfig;  
  
/** 
 * 使用Redis存儲Ticket 
 * @author xyong
 */  
public class RedisTicketRegistry extends AbstractDistributedTicketRegistry  
{  
  
    private static int redisDatabaseNum;  
  
    private static String hosts;  
      
    private static int port;  
      
    private static int connTimeout;  
      
    //private static String redisPassword;  
  
    /** 
     * ST最大空閒時間 
     */  
    private static int st_time;  
  
    /** 
     * TGT最大空閒時間 
     */  
    private static int tgt_time;  
  
    private static JedisPool cachePool;  
  
    static  
    {  
        
        
        //redisDatabaseNum = SysPropertiesUtil.getPropertyInt("redis_database_num");  
        redisDatabaseNum = 7;   //選擇存儲的redis數據庫,redis默認有15個數據庫。我的幸運數字是7,所以我選用第七個數據庫。
        
        //hosts = SysPropertiesUtil.getProperty("redis_hosts");  
        hosts = "10.4.123.100";
                
        //port = SysPropertiesUtil.getPropertyInt("redis_port");  
        port = 6379;
        
        //connTimeout = SysPropertiesUtil.getPropertyInt("redis_conn_timeout");  


        
        //redisPassword = SysPropertiesUtil.getProperty("redis_password");  
  
        //st_time = SysPropertiesUtil.getPropertyInt("st_time");  
        st_time = 10000;        //10秒
                
        //tgt_time = SysPropertiesUtil.getPropertyInt("tgt_time");  
        tgt_time = 7200000;     //7200秒,2個小時
        
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(1000);
        //config.setTestOnBorrow(true);
        cachePool = new JedisPool(config, hosts, port);  
    }  
  
    @Override  
    public void addTicket(Ticket ticket)  
    {  
        Jedis jedis = cachePool.getResource();  
  
        jedis.select(redisDatabaseNum);  
  
        int seconds = 0;  
  
        String key = ticket.getId();  
  
        if (ticket instanceof TicketGrantingTicket)  
        {  
            seconds = tgt_time / 1000;  
        }  
        else  
        {  
            seconds = st_time / 1000;  
        }  
  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = null;  
  
        try  
        {  
  
            oos = new ObjectOutputStream(bos);  
  
            oos.writeObject(ticket);  
  
        }  
        catch (Exception e)  
        {  
            logger.error("adding ticket to redis error.");  
        }  
        finally  
        {  
            try  
            {  
                if (null != oos)  
                    oos.close();  
  
            }  
            catch (Exception e)  
            {  
                logger.error("oos closing error when adding ticket to redis.");  
            }  
        }  
  
        jedis.set(key.getBytes(), bos.toByteArray());  
        jedis.expire(key.getBytes(), seconds);  //設置redis失效時間
        jedis.close();  
  
    }  
  
    @Override  
    public boolean deleteTicket(String ticketId)  
    {  
        if (ticketId == null)  
        {  
            return false;  
        }  
  
        Jedis jedis = cachePool.getResource();  
        jedis.select(redisDatabaseNum);  
          
        jedis.del(ticketId.getBytes());  
        jedis.close();  
        return true;  
    }  
  
    @Override  
    public Ticket getTicket(String ticketId)  
    {  
        return getProxiedTicketInstance(getRawTicket(ticketId));  
    }  
  
    private Ticket getRawTicket(final String ticketId)  
    {  
        if (null == ticketId)  
        {  
            return null;  
        }  
  
        Jedis jedis = cachePool.getResource();  
        jedis.select(redisDatabaseNum);  
        Ticket ticket = null;  
        byte[] bytes = jedis.get(ticketId.getBytes());  
        if (bytes == null || bytes.length < 1)  
        {  
            return null;  
        }  
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);  
        ObjectInputStream ois = null;  
  
        try  
        {  
            ois = new ObjectInputStream(bais);  
            ticket = (Ticket) ois.readObject();  
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
            logger.error("getting ticket to redis error.");  
        }  
        finally  
        {  
            try  
            {  
                if (null != ois)  
                {  
                    ois.close();  
                }  
            }  
            catch (Exception e)  
            {  
                e.printStackTrace();  
                logger.error("ois closing error when getting ticket to redis.");  
            }  
        }  
  
        jedis.close();  
        return ticket;  
    }  
  
    @Override  
    public Collection<Ticket> getTickets()  
    {  
        throw new UnsupportedOperationException("GetTickets not supported.");    
    }  
  
    @Override  
    protected boolean needsCallback()  
    {  
        return false;  
    }  
  
    @Override  
    protected void updateTicket(Ticket ticket)  
    {  
        this.addTicket(ticket);    
    }  
  
}
    找到myeclipse  workspace中RedisTicketRegistry.class文件,該文件在workspace\CASTransform\WebRoot\WEB-INF\classes\org\jasig\cas\ticket目錄下。
右鍵打開cas-server-core-4.0.0.jar壓縮包(不要解壓),再按照\org\jasig\cas\ticket\路徑打開文件夾,將RedisTicketRegistry.class拖到該文件夾下,結果如圖2.5.3.1所示。
 
圖2.5.3.1
    關掉該窗口,用修改後的cas-server-core-4.0.0.jar覆蓋CAS服務器cas/WEB-INF/lib下的原cas-server-core-4.0.0.jar包。

2.5.3.2、修改ticketRegistry.xml

    在CAS的cas/WEB-INF/spring-configuration下獲取ticketRegistry.xml。打開ticketRegistry.xml,修改id爲ticketRegistry的bean的路徑,並註釋掉ticketRegistry.xml下方的配置信息,修改後的ticketRegistry.xml內容如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!--


    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.


-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <description>
        Configuration for the default TicketRegistry which stores the tickets in-memory and cleans them out as specified intervals.
    </description>
       
  <!-- Ticket Registry -->
  <!-- <bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.DefaultTicketRegistry" /> -->
    <bean id="ticketRegistry" class="org.jasig.cas.ticket.RedisTicketRegistry" />


    <!--Quartz -->
    <!-- TICKET REGISTRY CLEANER -->
  
   
<!-- <bean id="ticketRegistryCleaner" class="org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner"
  p:ticketRegistry-ref="ticketRegistry"
  p:logoutManager-ref="logoutManager" />


<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" /> -->




</beans>
備註:你可以直接用上面的配置信息覆蓋掉你原來的ticketRegistry.xml配置信息。
    用修改後的ticketRegistry.xml覆蓋掉CAS服務器中原來的ticketRegistry.xml

2.5.4、測試

    按照以上步驟完成對CAS服務器的配置,重啓CAS服務器,瀏覽器訪問CAS登錄頁面,進行登錄操作,登錄成功後打開RedisDesktopManager(2.5.2安裝的Redis客戶端)。發現redis第七個數據中新增了cas ticket數據,如圖2.5.4.1,說明配置成功。
 
圖2.5.4.1
發現了一篇關於Jedis使用的文章,講的挺好的,大家可以看看。RedisUtil工具類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章