|
|
|
@ -0,0 +1,151 @@
|
|
|
|
|
package com.sztzjy.forex.trading_trading.config.security;
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
|
import org.springframework.core.log.LogMessage;
|
|
|
|
|
import org.springframework.security.core.session.*;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
import java.util.concurrent.ConcurrentMap;
|
|
|
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义session管理
|
|
|
|
|
* 该方法创建是为解决同一个用户在同一台电脑调同一个接口SessionRegistryImpl的registerNewSession会生成不同的会话id(相当于一个用户在缓存中有好几个会话id)
|
|
|
|
|
* 故重构该方法便于后台管理sessionId
|
|
|
|
|
*
|
|
|
|
|
* @author 陈沅
|
|
|
|
|
* @date 2023/07/06 22:27:47
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
@Component
|
|
|
|
|
public class CustomSessionRegistry implements SessionRegistry {
|
|
|
|
|
protected final Log logger = LogFactory.getLog(CustomSessionRegistry.class);
|
|
|
|
|
private final ConcurrentMap<Object, Set<String>> principals;
|
|
|
|
|
private final Map<String, SessionInformation> sessionIds;
|
|
|
|
|
|
|
|
|
|
public CustomSessionRegistry() {
|
|
|
|
|
this.principals = new ConcurrentHashMap();
|
|
|
|
|
this.sessionIds = new ConcurrentHashMap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CustomSessionRegistry(ConcurrentMap<Object, Set<String>> principals, Map<String, SessionInformation> sessionIds) {
|
|
|
|
|
this.principals = principals;
|
|
|
|
|
this.sessionIds = sessionIds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<Object> getAllPrincipals() {
|
|
|
|
|
return new ArrayList(this.principals.keySet());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<SessionInformation> getAllSessions(Object principal, boolean includeExpiredSessions) {
|
|
|
|
|
Set<String> sessionsUsedByPrincipal = (Set)this.principals.get(principal);
|
|
|
|
|
if (sessionsUsedByPrincipal == null) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
} else {
|
|
|
|
|
List<SessionInformation> list = new ArrayList(sessionsUsedByPrincipal.size());
|
|
|
|
|
Iterator var5 = sessionsUsedByPrincipal.iterator();
|
|
|
|
|
|
|
|
|
|
while(true) {
|
|
|
|
|
SessionInformation sessionInformation;
|
|
|
|
|
do {
|
|
|
|
|
do {
|
|
|
|
|
if (!var5.hasNext()) {
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String sessionId = (String)var5.next();
|
|
|
|
|
sessionInformation = this.getSessionInformation(sessionId);
|
|
|
|
|
} while(sessionInformation == null);
|
|
|
|
|
} while(!includeExpiredSessions && sessionInformation.isExpired());
|
|
|
|
|
|
|
|
|
|
list.add(sessionInformation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SessionInformation getSessionInformation(String sessionId) {
|
|
|
|
|
Assert.hasText(sessionId, "SessionId required as per interface contract");
|
|
|
|
|
return (SessionInformation)this.sessionIds.get(sessionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onApplicationEvent(AbstractSessionEvent event) {
|
|
|
|
|
String oldSessionId;
|
|
|
|
|
if (event instanceof SessionDestroyedEvent) {
|
|
|
|
|
SessionDestroyedEvent sessionDestroyedEvent = (SessionDestroyedEvent)event;
|
|
|
|
|
oldSessionId = sessionDestroyedEvent.getId();
|
|
|
|
|
this.removeSessionInformation(oldSessionId);
|
|
|
|
|
} else if (event instanceof SessionIdChangedEvent) {
|
|
|
|
|
SessionIdChangedEvent sessionIdChangedEvent = (SessionIdChangedEvent)event;
|
|
|
|
|
oldSessionId = sessionIdChangedEvent.getOldSessionId();
|
|
|
|
|
if (this.sessionIds.containsKey(oldSessionId)) {
|
|
|
|
|
Object principal = ((SessionInformation)this.sessionIds.get(oldSessionId)).getPrincipal();
|
|
|
|
|
this.removeSessionInformation(oldSessionId);
|
|
|
|
|
this.registerNewSession(sessionIdChangedEvent.getNewSessionId(), principal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void refreshLastRequest(String sessionId) {
|
|
|
|
|
Assert.hasText(sessionId, "SessionId required as per interface contract");
|
|
|
|
|
SessionInformation info = this.getSessionInformation(sessionId);
|
|
|
|
|
if (info != null) {
|
|
|
|
|
info.refreshLastRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void registerNewSession(String sessionId, Object principal) {
|
|
|
|
|
Assert.hasText(sessionId, "SessionId required as per interface contract");
|
|
|
|
|
Assert.notNull(principal, "Principal required as per interface contract");
|
|
|
|
|
if(principal instanceof JwtUser){
|
|
|
|
|
sessionId = ((JwtUser) principal).getUsername();
|
|
|
|
|
}
|
|
|
|
|
if (this.getSessionInformation(sessionId) != null) {
|
|
|
|
|
this.removeSessionInformation(sessionId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.logger.isDebugEnabled()) {
|
|
|
|
|
this.logger.debug(LogMessage.format("Registering session %s, for principal %s", sessionId, principal));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.sessionIds.put(sessionId, new SessionInformation(principal, sessionId, new Date()));
|
|
|
|
|
String finalSessionId = sessionId;
|
|
|
|
|
this.principals.compute(principal, (key, sessionsUsedByPrincipal) -> {
|
|
|
|
|
if (sessionsUsedByPrincipal == null) {
|
|
|
|
|
sessionsUsedByPrincipal = new CopyOnWriteArraySet();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
((Set)sessionsUsedByPrincipal).add(finalSessionId);
|
|
|
|
|
this.logger.trace(LogMessage.format("Sessions used by '%s' : %s", principal, sessionsUsedByPrincipal));
|
|
|
|
|
return (Set)sessionsUsedByPrincipal;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void removeSessionInformation(String sessionId) {
|
|
|
|
|
Assert.hasText(sessionId, "SessionId required as per interface contract");
|
|
|
|
|
SessionInformation info = this.getSessionInformation(sessionId);
|
|
|
|
|
if (info != null) {
|
|
|
|
|
if (this.logger.isTraceEnabled()) {
|
|
|
|
|
this.logger.debug("Removing session " + sessionId + " from set of registered sessions");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.sessionIds.remove(sessionId);
|
|
|
|
|
this.principals.computeIfPresent(info.getPrincipal(), (key, sessionsUsedByPrincipal) -> {
|
|
|
|
|
this.logger.debug(LogMessage.format("Removing session %s from principal's set of registered sessions", sessionId));
|
|
|
|
|
sessionsUsedByPrincipal.remove(sessionId);
|
|
|
|
|
if (sessionsUsedByPrincipal.isEmpty()) {
|
|
|
|
|
this.logger.debug(LogMessage.format("Removing principal %s from registry", info.getPrincipal()));
|
|
|
|
|
sessionsUsedByPrincipal = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.logger.trace(LogMessage.format("Sessions used by '%s' : %s", info.getPrincipal(), sessionsUsedByPrincipal));
|
|
|
|
|
return sessionsUsedByPrincipal;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|