瀏覽代碼

OnlineTicket

Crystal.Sea 4 年之前
父節點
當前提交
cd00a039c9
共有 15 個文件被更改,包括 131 次插入21 次删除
  1. 7 2
      maxkey-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java
  2. 4 3
      maxkey-core/src/main/java/org/maxkey/authn/SigninPrincipal.java
  3. 36 3
      maxkey-core/src/main/java/org/maxkey/authn/online/InMemoryOnlineTicketServices.java
  4. 17 1
      maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicket.java
  5. 5 0
      maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicketServices.java
  6. 28 1
      maxkey-core/src/main/java/org/maxkey/authn/online/RedisOnlineTicketServices.java
  7. 1 1
      maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/OnlineTicketEndpoint.java
  8. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java
  9. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java
  10. 1 1
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java
  11. 1 1
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java
  12. 1 1
      maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java
  13. 1 1
      maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java
  14. 8 0
      maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LogoutEndpoint.java
  15. 19 4
      maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java

+ 7 - 2
maxkey-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java

@@ -149,6 +149,9 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
         String onlineTickitId = WebConstants.ONLINE_TICKET_PREFIX + "-" + java.util.UUID.randomUUID().toString().toLowerCase();
         _logger.debug("set online Tickit Cookie " + onlineTickitId + " on domain "+ this.applicationConfig.getBaseDomainName());
         
+        OnlineTicket onlineTicket = new OnlineTicket(onlineTickitId);
+        
+        
         WebContext.setCookie(WebContext.getResponse(), 
                 this.applicationConfig.getBaseDomainName(), 
                 WebConstants.ONLINE_TICKET_NAME, 
@@ -157,7 +160,7 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
         
         SigninPrincipal signinPrincipal = new SigninPrincipal(userInfo);
         //set OnlineTicket
-        signinPrincipal.setOnlineTicket(onlineTickitId);
+        signinPrincipal.setOnlineTicket(onlineTicket);
         ArrayList<GrantedAuthority> grantedAuthoritys = authenticationRealm.grantAuthority(userInfo);
         //set default roles
         grantedAuthoritys.add(new SimpleGrantedAuthority("ROLE_USER"));
@@ -182,8 +185,10 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
         authenticationToken.setDetails(
                 new WebAuthenticationDetails(WebContext.getRequest()));
         
-        OnlineTicket onlineTicket = new OnlineTicket(onlineTickitId,authenticationToken);
+        onlineTicket.setAuthentication(authenticationToken);
+        
         this.onlineTicketServices.store(onlineTickitId, onlineTicket);
+        
         /*
          *  put userInfo to current session context
          */

+ 4 - 3
maxkey-core/src/main/java/org/maxkey/authn/SigninPrincipal.java

@@ -20,6 +20,7 @@ package org.maxkey.authn;
 import java.util.ArrayList;
 import java.util.Collection;
 
+import org.maxkey.authn.online.OnlineTicket;
 import org.maxkey.domain.UserInfo;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -31,7 +32,7 @@ public class SigninPrincipal implements  UserDetails {
     
     UserDetails userDetails;
     
-    String onlineTicket;
+    OnlineTicket onlineTicket;
     ArrayList<GrantedAuthority> grantedAuthority;
     boolean authenticated;
     boolean roleAdministrators;
@@ -95,11 +96,11 @@ public class SigninPrincipal implements  UserDetails {
         this.grantedAuthority = grantedAuthority;
     }
 
-    public String getOnlineTicket() {
+    public OnlineTicket getOnlineTicket() {
         return onlineTicket;
     }
 
-    public void setOnlineTicket(String onlineTicket) {
+    public void setOnlineTicket(OnlineTicket onlineTicket) {
         this.onlineTicket = onlineTicket;
     }
 

+ 36 - 3
maxkey-core/src/main/java/org/maxkey/authn/online/InMemoryOnlineTicketServices.java

@@ -18,15 +18,19 @@
 package org.maxkey.authn.online;
 
 import java.time.Duration;
+import java.time.LocalTime;
 
 import org.ehcache.UserManagedCache;
 import org.ehcache.config.builders.ExpiryPolicyBuilder;
 import org.ehcache.config.builders.UserManagedCacheBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 public class InMemoryOnlineTicketServices implements OnlineTicketServices{
-
-	protected final static  UserManagedCache<String, OnlineTicket> onlineTicketStore = 
+    private static final Logger _logger = LoggerFactory.getLogger(InMemoryOnlineTicketServices.class);
+    
+	protected  static  UserManagedCache<String, OnlineTicket> onlineTicketStore = 
 			UserManagedCacheBuilder.newUserManagedCacheBuilder(String.class, OnlineTicket.class)
 				.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(30)))
 				.build(true);
@@ -56,8 +60,37 @@ public class InMemoryOnlineTicketServices implements OnlineTicketServices{
 
     @Override
     public void setValiditySeconds(int validitySeconds) {
-        // TODO Auto-generated method stub
+        onlineTicketStore = 
+                UserManagedCacheBuilder.
+                    newUserManagedCacheBuilder(String.class, OnlineTicket.class)
+                    .withExpiry(
+                            ExpiryPolicyBuilder.timeToLiveExpiration(
+                                    Duration.ofMinutes(validitySeconds/60))
+                     )
+                    .build(true);
+        
+    }
+
+    @Override
+    public void refresh(String ticketId,LocalTime refreshTime) {
+        OnlineTicket onlineTicket = get(ticketId);
+        onlineTicket.setTicketTime(refreshTime);
+        store(ticketId , onlineTicket);
+    }
+
+    @Override
+    public void refresh(String ticketId) {
+        OnlineTicket onlineTicket = get(ticketId);
+        
+        LocalTime currentTime = LocalTime.now();
+        Duration duration = Duration.between(currentTime, onlineTicket.getTicketTime());
+        
+        _logger.trace("OnlineTicket duration " + duration.getSeconds());
         
+        if(duration.getSeconds() > OnlineTicket.MAX_EXPIRY_DURATION) {
+            onlineTicket.setTicketTime(currentTime);
+            refresh(ticketId,currentTime);
+        }
     }
 
 }

+ 17 - 1
maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicket.java

@@ -1,6 +1,7 @@
 package org.maxkey.authn.online;
 
 import java.io.Serializable;
+import java.time.LocalTime;
 import java.util.HashMap;
 
 import org.maxkey.domain.apps.Apps;
@@ -11,10 +12,15 @@ public class OnlineTicket implements Serializable{
     /**
      * 
      */
-    private static final long serialVersionUID = 9008067569150338296L;
+    
+    public static final  int    MAX_EXPIRY_DURATION = 60 * 10; //default 10 minutes.
+    
+    private static final long   serialVersionUID = 9008067569150338296L;
 
     public String ticketId;
     
+    public LocalTime ticketTime;
+    
     public Authentication authentication;
     
     private HashMap<String , Apps> authorizedApps = new HashMap<String , Apps>();
@@ -23,12 +29,14 @@ public class OnlineTicket implements Serializable{
     public OnlineTicket(String ticketId) {
         super();
         this.ticketId = ticketId;
+        this.ticketTime = LocalTime.now();
     }
     
     public OnlineTicket(String ticketId,Authentication authentication) {
         super();
         this.ticketId = ticketId;
         this.authentication = authentication;
+        this.ticketTime = LocalTime.now();
     }
     
     
@@ -44,6 +52,14 @@ public class OnlineTicket implements Serializable{
     }
 
     
+    public LocalTime getTicketTime() {
+        return ticketTime;
+    }
+
+    public void setTicketTime(LocalTime ticketTime) {
+        this.ticketTime = ticketTime;
+    }
+
     public Authentication getAuthentication() {
         return authentication;
     }

+ 5 - 0
maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicketServices.java

@@ -17,6 +17,7 @@
 
 package org.maxkey.authn.online;
 
+import java.time.LocalTime;
 
 public interface OnlineTicketServices {
 
@@ -25,6 +26,10 @@ public interface OnlineTicketServices {
     public  OnlineTicket remove(String ticket);
     
     public  OnlineTicket get(String ticketId);
+    
+    public void refresh(String ticketId ,LocalTime refreshTime);
+    
+    public void refresh(String ticketId);
 
     public void setValiditySeconds(int validitySeconds);
 }

+ 28 - 1
maxkey-core/src/main/java/org/maxkey/authn/online/RedisOnlineTicketServices.java

@@ -17,12 +17,17 @@
 
 package org.maxkey.authn.online;
 
+import java.time.Duration;
+import java.time.LocalTime;
+
 import org.maxkey.persistence.redis.RedisConnection;
 import org.maxkey.persistence.redis.RedisConnectionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 public class RedisOnlineTicketServices implements OnlineTicketServices {
-
+    private static final Logger _logger = LoggerFactory.getLogger(RedisOnlineTicketServices.class);
 	
 	protected int serviceTicketValiditySeconds = 60 * 30; //default 30 minutes.
 	
@@ -78,5 +83,27 @@ public class RedisOnlineTicketServices implements OnlineTicketServices {
         
     }
 
+    @Override
+    public void refresh(String ticketId,LocalTime refreshTime) {
+        OnlineTicket onlineTicket = get(ticketId);
+        onlineTicket.setTicketTime(refreshTime);
+        store(ticketId , onlineTicket);
+    }
+    
+    @Override
+    public void refresh(String ticketId) {
+        OnlineTicket onlineTicket = get(ticketId);
+        
+        LocalTime currentTime = LocalTime.now();
+        Duration duration = Duration.between(currentTime, onlineTicket.getTicketTime());
+        
+        _logger.trace("OnlineTicket duration " + duration.getSeconds());
+        
+        if(duration.getSeconds() > OnlineTicket.MAX_EXPIRY_DURATION) {
+            onlineTicket.setTicketTime(currentTime);
+            refresh(ticketId,currentTime);
+        }
+    }
+
 	
 }

+ 1 - 1
maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/OnlineTicketEndpoint.java → maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/endpoint/OnlineTicketEndpoint.java

@@ -1,4 +1,4 @@
-package org.maxkey.web.endpoint;
+package org.maxkey.authz.endpoint;
 
 import org.maxkey.authn.online.OnlineTicket;
 import org.maxkey.authn.online.OnlineTicketServices;

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java

@@ -135,7 +135,7 @@ public class CasAuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{
 		}
 		
 		if(casDetails.getLogoutType()==LogoutType.BACK_CHANNEL) {
-		    String onlineTicketId = ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket();
+		    String onlineTicketId = ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId();
 		    OnlineTicket onlineTicket  = onlineTicketServices.get(onlineTicketId);
 		    //set cas ticket as OnlineTicketId
 		    casDetails.setOnlineTicket(ticket);

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/adapter/CasDefaultAdapter.java

@@ -67,7 +67,7 @@ public class CasDefaultAdapter extends AbstractAuthorizeAdapter {
 		serviceResponseBuilder.setAttribute("departmentId", userInfo.getDepartmentId());
 		serviceResponseBuilder.setAttribute("workRegion",base64Attr(userInfo.getWorkRegion()));
 		
-		serviceResponseBuilder.setAttribute(WebConstants.ONLINE_TICKET_NAME,authentication.getOnlineTicket());
+		serviceResponseBuilder.setAttribute(WebConstants.ONLINE_TICKET_NAME,authentication.getOnlineTicket().getTicketId());
 	
 		return null;
 	}

+ 1 - 1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/OAuthDefaultUserInfoAdapter.java

@@ -45,7 +45,7 @@ public class OAuthDefaultUserInfoAdapter extends AbstractAuthorizeAdapter {
 		beanMap.put("title", userInfo.getJobTitle());
 		beanMap.put("state", userInfo.getWorkRegion());
 		beanMap.put("gender", userInfo.getGender());
-		beanMap.put(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket());
+		beanMap.put(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId());
 		
 		String info= JsonUtils.object2Json(beanMap);
 		

+ 1 - 1
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/userinfo/endpoint/UserInfoEndpoint.java

@@ -176,7 +176,7 @@ public class UserInfoEndpoint {
 			 SigninPrincipal authentication = (SigninPrincipal)oAuth2Authentication.getUserAuthentication().getPrincipal();
 			 
 			 jwtClaimsSetBuilder.claim("sub", userInfo.getId());
-			 jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket());
+			 jwtClaimsSetBuilder.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId());
 			 
 		 	if(scopes.contains("profile")){
 		 		jwtClaimsSetBuilder.claim("name", userInfo.getUsername());

+ 1 - 1
maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/provider/endpoint/AssertionEndpoint.java

@@ -73,7 +73,7 @@ public class AssertionEndpoint {
 		logger.debug("AuthnRequestInfo: {}", authnRequestInfo);
 
 		HashMap <String,String>attributeMap=new HashMap<String,String>();
-		attributeMap.put(WebConstants.ONLINE_TICKET_NAME, ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket());
+		attributeMap.put(WebConstants.ONLINE_TICKET_NAME, ((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId());
 		
 		//saml20Details
 		Response authResponse = authnResponseGenerator.generateAuthnResponse(

+ 1 - 1
maxkey-protocols/maxkey-protocol-tokenbased/src/main/java/org/maxkey/authz/token/endpoint/adapter/TokenBasedDefaultAdapter.java

@@ -72,7 +72,7 @@ public class TokenBasedDefaultAdapter extends AbstractAuthorizeAdapter {
 		}
 		
 		beanMap.put("displayName", userInfo.getDisplayName());
-		beanMap.put(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket());
+		beanMap.put(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId());
 		
 		/*
 		 * use UTC date time format

+ 8 - 0
maxkey-web-maxkey/src/main/java/org/maxkey/web/endpoint/LogoutEndpoint.java

@@ -20,6 +20,8 @@ package org.maxkey.web.endpoint;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.maxkey.authn.SigninPrincipal;
+import org.maxkey.authn.online.OnlineTicketServices;
 import org.maxkey.authn.realm.AbstractAuthenticationRealm;
 import org.maxkey.configuration.ApplicationConfig;
 import org.maxkey.web.WebConstants;
@@ -49,6 +51,10 @@ public class LogoutEndpoint {
 	@Autowired
 	ApplicationConfig applicationConfig;
 	
+	@Autowired
+    @Qualifier("onlineTicketServices")
+    protected OnlineTicketServices onlineTicketServices;
+	
  	@RequestMapping(value={"/logout"})
  	public ModelAndView logout(
  					HttpServletRequest request, 
@@ -89,8 +95,10 @@ public class LogoutEndpoint {
  		_logger.debug("re Login URL : "+ reLoginUrl);
  		
  		modelAndView.addObject("reloginUrl",reLoginUrl);
+ 	    onlineTicketServices.remove(((SigninPrincipal)WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId());
  		request.getSession().invalidate();
  		SecurityContextHolder.clearContext();
+ 		
  		modelAndView.setViewName(viewName);
  		return modelAndView;
  	}

+ 19 - 4
maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/PermissionAdapter.java

@@ -23,6 +23,9 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler;
+import org.maxkey.authn.SigninPrincipal;
+import org.maxkey.authn.online.OnlineTicket;
+import org.maxkey.authn.online.OnlineTicketServices;
 import org.maxkey.configuration.ApplicationConfig;
 import org.maxkey.constants.ConstantsPasswordSetType;
 import org.maxkey.web.WebConstants;
@@ -31,6 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
 import org.springframework.security.web.savedrequest.RequestCache;
 import org.springframework.security.web.savedrequest.SavedRequest;
@@ -57,6 +61,10 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
     SavedRequestAwareAuthenticationSuccessHandler savedRequestSuccessHandler;
     
     static ConcurrentHashMap<String, String> navigationsMap = null;
+    
+    @Autowired
+    @Qualifier("onlineTicketServices")
+    protected OnlineTicketServices onlineTicketServices;
 
     /*
      * 请求前处理 (non-Javadoc)
@@ -96,11 +104,12 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
             }
         }
         
+        Authentication authentication = WebContext.getAuthentication();
         //save  first protected url 
         SavedRequest  firstSavedRequest = (SavedRequest)WebContext.getAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
         // 判断用户是否登录, 判断用户和角色,判断用户是否登录用户
-        if  (WebContext.getAuthentication() == null 
-                || WebContext.getAuthentication().getAuthorities() == null) {
+        if  (authentication == null 
+                || authentication.getAuthorities() == null) {
             //保存未认证的请求信息
             if(firstSavedRequest==null){
                 RequestCache requestCache = new HttpSessionRequestCache();
@@ -119,14 +128,20 @@ public class PermissionAdapter extends HandlerInterceptorAdapter {
             return false;
         }
         
+        
         //认证完成,跳转到未认证请求
         if(firstSavedRequest!=null) {
-            savedRequestSuccessHandler.onAuthenticationSuccess(request, response, WebContext.getAuthentication());
+            savedRequestSuccessHandler.onAuthenticationSuccess(request, response, authentication);
             WebContext.removeAttribute(WebConstants.FIRST_SAVED_REQUEST_PARAMETER);
         }
 
         boolean hasAccess = true;
-
+        
+        if(authentication.getPrincipal() instanceof SigninPrincipal) {
+            SigninPrincipal signinPrincipal = (SigninPrincipal)authentication.getPrincipal();
+            OnlineTicket onlineTicket = signinPrincipal.getOnlineTicket();
+            onlineTicketServices.refresh(onlineTicket.getTicketId());
+        }
         /*
          * boolean preHandler = super.preHandle(request, response, handler);
          *