为了保证生产环境CAS(Central Authentication Service)认证服务的高可用,防止出现单点故障,我们需要对CAS Server进行集群部署。
CAS的Ticket默认是以Map的方式存储在JVM内存中的,多个tomcat之间无法共享,因此我们可以使用MemCached或者Redis来存储Ticket。MemCached的方式官方已经提供了解决方案,我们这里使用的是Redis,具体实现可以参考CAS的模块:cas-server-integration-memcached。
1、pom.xml文件中加入依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <version>2.7.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.0.RELEASE</version> </dependency>
2、参考:org.jasig.cas.ticket.registry.MemCacheTicketRegistry,重写Ticket注册类。
package com.***.cas.ticket.registry; import org.jasig.cas.ticket.ServiceTicket; import org.jasig.cas.ticket.Ticket; import org.jasig.cas.ticket.TicketGrantingTicket; import org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry; import org.springframework.beans.factory.DisposableBean; import org.springframework.data.redis.core.RedisTemplate; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import java.util.Collection; import java.util.concurrent.TimeUnit; public final class RedisTicketRegistry extends AbstractDistributedTicketRegistry implements DisposableBean { /** Memcached client. */ @NotNull private final RedisTemplate<String, Object> redisTemplate; /** * 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> redisTemplate, int tgtTimeout, int stTimeout) { this.redisTemplate = redisTemplate; this.tgtTimeout = tgtTimeout; this.stTimeout = stTimeout; } @Override public void addTicket(Ticket ticket) { logger.debug("Adding ticket {}", ticket); try { this.redisTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS); } catch (Exception e) { logger.error("Failed adding {}", ticket, e); } } @Override public Ticket getTicket(String ticketId) { try { final Ticket t = (Ticket) this.redisTemplate.opsForValue().get(ticketId); if (t != null) { return getProxiedTicketInstance(t); } } catch (final Exception e) { logger.error("Failed fetching {} ", ticketId, e); } return null; } @Override public boolean