`
xiang37
  • 浏览: 429471 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

CAS4.0分布式部署以及使用Redis缓存共享ticket

 
阅读更多

CAS4.0分布式部署以及使用Redis缓存共享ticket

         当业务不断拓展,系统用户在不断增加时,我们的平台统一登录认证服务无法承受当前压力。此时,我们需要分布式部署我们的统一登录认证服务。

         CAS的分布式部署,除了注意session共享,通过nginx或者apache反向代理外,还需要注意票据ticket的存储共享。

         ticketRegistry.xml文件中,配置ticket相关的信息。主要配置:1.注册ticket存储,2.定时清除过期ticket

         由于我们使用的Redis缓存Key设置了过期时间,因此可以注释掉清除过期ticket的定时器及相关类。

         编写新的ticket存储类需要继承类AbstractDistributedTicketRegistry。代码如下:

    

package 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 cn.net.xinyi.util.SysPropertiesUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 使用Redis存储Ticket
 * @author XIVA
 */
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");

        hosts = SysPropertiesUtil.getProperty("redis_hosts");
        
        port = SysPropertiesUtil.getPropertyInt("redis_port");

        connTimeout = SysPropertiesUtil.getPropertyInt("redis_conn_timeout");
        
        redisPassword = SysPropertiesUtil.getProperty("redis_password");

        st_time = SysPropertiesUtil.getPropertyInt("st_time");

        tgt_time = SysPropertiesUtil.getPropertyInt("tgt_time");

        cachePool = new JedisPool(new JedisPoolConfig(), hosts, port, connTimeout, redisPassword);
    }

    @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);
        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);  
    }

}

 

    变更后的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" />
  -->
  
  <!-- ticket store on redis db	-->
  <bean id="ticketRegistry" class="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>

 

    

    

分享到:
评论

相关推荐

    phpCAS源码以及调用示例(redis管理session,解决无法logout的问题)

    本文将深入探讨phpCAS的源码和调用示例,特别是在使用Redis管理session以及解决无法正常logout问题方面的应用。 首先,理解phpCAS的工作原理至关重要。phpCAS是一个基于PHP的客户端库,它遵循CAS协议与CAS服务器...

    cas-client 基于redis自定义实现

    在CAS客户端中使用Redis,可能是因为开发者需要更高效的票证管理和缓存策略,或者希望利用Redis的分布式特性来扩展CAS服务的可用性。 接下来,提到"可能会有bug,具体为何修改",这暗示了在原有CAS客户端的基础上...

    cas4.1.x集成mysql,ldap,redis(session和票据),写了简单的两个客户端demo

    在这个项目中,我们看到的是CAS 4.1.x版本,它已经成功地集成了MySQL数据库、LDAP身份验证服务以及Redis来存储会话和票据,以提高系统的性能和可扩展性。 1. **MySQL 集成**: - MySQL作为关系型数据库,用于存储...

    cas-overlay-template-6.4 服务端代码

    10.CAS-redisCluster集群存储ticket(相应redis必须配置成cluster集群) 11.CAS-加密存储ticket 12.CAS-实习动态验证码 13.CAS-实习自定义登录 14.CAS-实现自定义返回用户登录信息 15.CAS-页面缓存记住我 ----------...

    cas-server.zip

    此外,该版本的CAS还涉及到与数据库的交互以验证用户身份,以及使用Redis作为缓存存储用户信息,并能修改Redis中的键值。 1. **CAS SSO原理**: 单点登录是一种网络应用的认证机制,用户只需要登录一次就可以访问...

    cas4.1.x 集成 mysql,ldap,redis(session和票据),写了简单的两个客户端 demo.zip

    在本项目中,我们关注的是CAS 4.1.x版本,它集成了MySQL数据库、LDAP(Lightweight Directory Access Protocol)目录服务以及Redis作为session和票据管理的缓存系统。下面将详细阐述这些集成的关键知识点。 1. **...

    CAS-DEMO.zip

    由于提到"redis"标签,说明CAS可能使用Redis作为缓存或票据持久化存储。Redis是一个高性能的键值数据存储系统,常用于SSO场景中的票据管理,以提高性能和可扩展性。 6. **客户端配置**: CAS客户端库(如`cas-...

    singleLogin.rar

    这个解决方案基于Spring、SpringMVC(SSM)框架和Redis缓存技术。 首先,我们来了解一下SSO的核心原理。在SSO系统中,通常有一个中心认证服务器(Central Authentication Service,CAS),负责验证用户的身份。当...

    基于SpringBoot 2.0.3.RELEASE+Mybatis+Redis的SSO单点登录系统

    Redis是一个高性能的键值对内存数据库,常用于缓存和消息中间件。在这个SSO系统中,Redis主要承担会话管理的角色。它可以存储用户的登录状态,实现跨应用的会话共享。当用户在系统A登录后,其登录状态会被保存到...

    java_bootstrap.zip

    - 存储Token时,可以将它们保存在内存、数据库或分布式缓存(如Redis)中,根据项目规模和性能需求选择合适的方式。 - 验证Token时,接收方应用会解码Token,检查其签名、有效期和携带的信息,确保Token的有效性。...

    一个sso的解决方案

    在这个解决方案中,我们利用Redis作为缓存存储TGT。Redis是一个高性能的键值存储系统,适合处理大量的短期、临时数据,如票据。以下是一些关键步骤: 1. **用户登录**:用户首次访问任一应用时,如果未登录,会被...

    Sa-Token:这可能是史上功能最全的Java权限认证框架!目前已集成——登录认证、权限认证、分布式Session会话、微服务网关鉴权、单点登录、OAuth2.0、踢人下线、Redis集成、前后台分离、记住我模式、模拟他人账号、临时身份切换、账号封禁、多账号认证体系、注解式鉴权、路由拦截式鉴权、花式token生成、自动续签、同端互斥登录、会话治理、密码加密、jwt集成、Spring集成、WebFlux集成..

    Token,你将以一种极其简单的方式实现系统的权限认证部分登录认证 —— 单端登录、多端登录、同端互斥登录、七天内免登录权限认证 —— 权限认证、角色认证、会话二级认证Session会话 —— 全端共享Session、单端独...

    sso-test01

    - **Redis**:作为一种内存数据结构存储系统,Redis常用于缓存和高速数据交换。在SSO中,Redis可以作为临时存储TGT的地方,因为它的快速读写性能有助于提高SSO的响应速度。用户登录时,将TGT存储在Redis中,后续...

    dddl.rar_单点登录C#

    这可以通过使用分布式缓存(如Redis或Memcached)或数据库存储来实现。 4. 通信协议:实现SSO的常见协议有CAS(Central Authentication Service)、SAML(Security Assertion Markup Language)和OAuth等。这些协议...

    SSO(单点登录)

    总的来说,实现SSO涉及多个层面的技术整合,包括Spring Security的配置、CAS服务器的设置、以及像Redis这样的缓存服务来确保会话信息的安全和高效管理。这是一项复杂但重要的任务,对于提升企业信息化系统的用户体验...

    java统一认证中心单点登录系统源码,开箱即用

    3. **Redis缓存**: Redis可能被用于存储用户的会话信息和票据,因为其高效的键值存储、快速的数据读写能力,以及对分布式环境的良好支持,使得Redis成为SSO系统中常见的数据存储解决方案。 4. **数据库配置**: ...

    单点登录asp。net实现

    - **分布式会话存储**:使用Redis或Memcached等分布式缓存,解决大型分布式系统中的会话共享问题。 6. **实际应用** - **企业内部系统**:如ERP、CRM、OA等多系统环境,员工只需要登录一次即可访问所有系统。 - ...

    java版ss源码-UniAuth:统一认证

    security4+cas+cxf作为基础框架,数据库为mysql5.7,配置管理使用zookeeper3.4,redis用于存储ticket,缓存使用,前端使用angularJS 1.x; 二. 快速开始 2.1.编译打包 在源码目录执行命令 (gradle版本2.12) gradle ...

    单点登录系统

    - **缓存机制**:使用缓存(如Redis)存储用户登录状态,减少数据库查询,提高响应速度。 - **异步处理**:对于耗时操作(如发送短信验证码),可采用异步处理,提高系统吞吐量。 - **安全设计**:确保SSO系统安全,...

    OneMachineLogin:一机登录演示

    8. **分布式缓存**:为了提高性能和减少数据库压力,项目可能使用Redis或Memcached等分布式缓存来存储session信息,尤其是在高并发环境下。 9. **HTTPS与安全性**:考虑到敏感的用户信息,项目可能使用HTTPS协议...

Global site tag (gtag.js) - Google Analytics