為了保證生產環境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 deleteTicket(String 