cas-server集群部署无法实现单点登录问题
当cas-server部署到生产环境时,是三台服务器用nginx的负载均衡的集群模式,会出现其中一个项目登录成功后,访问另一个项目有时候还需要登录,是因为cas-server的tgt是存在tomcat的内存中,两个项目可能会访问到不同的服务器,所以要实现共享ticket。这里使用的是redis
修改/WEB-INF/spring-configuration/ticketRegistry.xml
<bean id="ticketRegistry" class="com.sys.action.RedisTicketRegistry" />
cas-server提供了一个集群的抽象类,AbstractDistributedTicketRegistry,我们需要实现里面的方法。
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Collection; import org.apache.log4j.Logger; import org.jasig.cas.ticket.ServiceTicketImpl; import org.jasig.cas.ticket.Ticket; import org.jasig.cas.ticket.TicketGrantingTicket; import org.jasig.cas.ticket.TicketGrantingTicketImpl; import org.jasig.cas.ticket.registry.AbstractDistributedTicketRegistry; import com.genilex.utils.PropertiesUtil; import com.genilex.utils.RedisCache; public class RedisTicketRegistry extends AbstractDistributedTicketRegistry { private static final Logger log = Logger.getLogger(RedisTicketRegistry.class); //ST最大空闲时间 private static int st_time = PropertiesUtil.getPropertyInt("st_time"); //TGT最大空闲时间 private static int tgt_time = PropertiesUtil.getPropertyInt("tgt_time"); @Override protected boolean needsCallback() { return false; } @Override protected void updateTicket(final Ticket ticket) { System.out.println("updateTicket---tikcet:"+ticket); addTicket(ticket); } @Override public void addTicket(final Ticket ticket) { System.out.println("addTicket---ticket:"+ticket); int seconds = 0; String key = ticket.getId() ; if(ticket instanceof TicketGrantingTicket){ seconds = tgt_time; }else{ seconds = st_time; } ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try{ oos = new ObjectOutputStream(bos); oos.writeObject(ticket); }catch(Exception e){ log.error("adding ticket to redis error."); }finally{ try{ if(null!=oos) oos.close(); }catch(Exception e){ log.error("oos closing error when adding ticket to redis."); } } RedisCache.set(key.getBytes(), bos.toByteArray(), seconds); } @Override public boolean deleteTicket(final String ticketId) { System.out.println("deleteTicket---ticketId:"+ticketId); if (ticketId == null) { return false; } RedisCache.del(ticketId.getBytes()); return true; } @Override public Ticket getTicket(final String ticketId) { System.out.println("getTicket---ticketId:"+ticketId); if(null == ticketId) { return null; } byte[] ticketByte = RedisCache.get(ticketId.getBytes()); if(ticketByte == null) { return null; } Ticket ticket = null; ByteArrayInputStream bais = new ByteArrayInputStream(ticketByte); ObjectInputStream ois = null; try{ ois = new ObjectInputStream(bais); ticket = (Ticket)ois.readObject(); }catch(Exception e){ log.error("getting ticket to redis error."); }finally{ try{ if(null!=ois) ois.close(); }catch(Exception e){ log.error("ois closing error when getting ticket to redis."); } } return getProxiedTicketInstance(ticket); } /** * 取得当前用户名 * @param ticket * @return */ private String getUsername(Ticket ticket){ TicketGrantingTicket t = null; try { t = (TicketGrantingTicketImpl)ticket; }catch (Exception e){ t = ((ServiceTicketImpl)ticket).getGrantingTicket(); } return t.getAuthentication().getPrincipal().getId(); } @Override public Collection<Ticket> getTickets() { throw new UnsupportedOperationException("GetTickets not supported."); }