CAS 4.0 更改token存储方式(redis)后,产生的单点登出问题?

思路: 上一篇文章中,把TGT存入了redis集群中,跟踪代码后发现,在ticket对象中还存放着所有访问的server信息,因为当登出时,会往每个曾经访问过CAS客端发送登出信息。因为修改了存储方式,导致该对像无数据。所以我们要把server信息也存入redis中, 退出时取出。

CentralAuthenticationServiceImpl.java中介入,grantServiceTicket() 该方法是生成TOKEN及存储的。


        final ServiceTicket serviceTicket = ticketGrantingTicket.grantServiceTicket(generatedServiceTicketId, service,
                this.serviceTicketExpirationPolicy, credentials != null);//存service  , 单点拿出时拿出来用。lumz

        //add by lumz for store service to redis
        if (ticketGrantingTicket != null){
        	HashMap sm = new HashMap();//缓存MAP
        	HashMap sm1 = new HashMap();//临时MAP
        	String key = ticketGrantingTicket.getId()+ticketGrantingTicket.getAuthentication().getPrincipal().getId();
        	sm = this.ticketRegistry.getTicketService(key);
        	if(sm == null ){ //判断REDIS是否已缓存
        		sm1.put(generatedServiceTicketId, service);
        		this.ticketRegistry.addTicketService(key, sm1);
        	}else{
        		if(sm.containsValue(service)!=true){
        			sm.put(generatedServiceTicketId, service);
            		this.ticketRegistry.updateTicketService(key, sm);
        		}
        		
        	}
        }
        //end add
        this.serviceTicketRegistry.addTicket(serviceTicket);//redis add ticket lumz

destroyTicketGrantingTicket(final String ticketGrantingTicketId) 注销时调用的方法:

//        final List logoutRequests = logoutManager.performLogout(ticket); //modify by lumz for retieve the data from redis.
        String key = ticket.getId()+ticket.getAuthentication().getPrincipal().getId();
        Map services =  this.ticketRegistry.getTicketService(key);
        final List logoutRequests = logoutManager.performLogout(ticket, services); 
        this.ticketRegistry.deleteTicket(ticketGrantingTicketId);
        this.ticketRegistry.deleteTicket(key);//add by lumz , after clean tgt token , we need to clear the server info.

LogoutManagerImpl.java 新加一个方法,多加了一个参数,在上面高亮处调用。

    @Override
    public List performLogout(final TicketGrantingTicket ticket,Map services) {
        
        // synchronize the retrieval of the services and their cleaning for the TGT
        // to avoid concurrent logout mess ups
        synchronized (ticket) {
//            services = ticket.getServices(); //modify by lumz 2016-9-2 13:49:15
        	if(services == null)
        		services = ticket.getServices();//if the value is null, init the value to {}
            ticket.removeAllServices();
        }
...COPY  performLogout(final TicketGrantingTicket ticket)方法,做相应的更改。

 
  

RedisTicketRegistry.java 新封装了存储server的方法

//add by lumz 2016年9月2日10:44:01 for store service data to REDIS  SERVER.  logoutAction can get this servers to send notification to ever node when user logou(slo).
	@Override
	public void addTicketService(String key, HashMap services) {
	    logger.debug("Adding Service ticket {}", key);
	    try {
	    	/*reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);*/
	    	//序列化
	    	ObjectsTranscoder> objTranscoder =  new ObjectsTranscoder>();
	    	byte[] result1 = objTranscoder.serialize(services);
//	    	Ticket userA_userA = objTranscoder.deserialize(result1); 
	    	handle.set(key.getBytes(), result1, this.tgtTimeout);
	    	logger.info("-----CoreRdisTicketRegistry { ADD ticket service: } ------" + key);
	    } catch (final Exception e) {
	        logger.error("Failed adding {}", key, e);
	    }
	}
	@Override
	public HashMap getTicketService(String key) {
		 HashMap tic =null;
	     try {
	    	 	
	            /*final Ticket t = (Ticket) this.reidsTemplate.opsForValue().get(ticketId);*/
	    		String defaultvalue = "";
	    	 	byte[] result = this.handle.get(key.getBytes(), defaultvalue.getBytes());
	    	 	
	    	 	if ("".equals(result)) {
	 	            return null;
	 	        }
	    	 	//序列化
		    	ObjectsTranscoder> objTranscoder =  new ObjectsTranscoder>();
		    	tic = objTranscoder.deserialize(result);
    	
	            if (tic != null) {
	            	logger.debug("Ticket [{}] found in registry.", key);
	            }
	            logger.info("---- CoreRdisTicketRegistry { GET ticket Service : "+ key +" } -----" );
	        } catch (final Exception e) {
	            logger.error("Failed fetching {} ", key, e);
	        }
	        return tic;
	}
	@Override
	public void updateTicketService(String key, HashMap services) {
		 logger.debug("Updating ticket {}", key);
		    try {
		    	
		          /*this.reidsTemplate.delete(ticket.getId());
		          reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);*/
		    	this.handle.del(key);
		    	//序列化
		    	ObjectsTranscoder> objTranscoder =  new ObjectsTranscoder>();
		    	byte[] result1 = objTranscoder.serialize(services);
		    	handle.set(key.getBytes(), result1, this.tgtTimeout);
		    	logger.info("----CoreRdisTicketRegistry { UPDATE ticket Service: }-----" + key);
		    } catch (final Exception e) {
		        logger.error("Failed updating {}", key, e);
		    }
		}
	




你可能感兴趣的:(CAS)