mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-05-22 01:42:00 +00:00
Update CustomHttpSessionListener.java
This commit is contained in:
parent
8876d31bf7
commit
b080704bcd
@ -1,57 +1,200 @@
|
|||||||
package stirling.software.SPDF.config.security.session;
|
package stirling.software.SPDF.config.security.session;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.session.SessionInformation;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
import jakarta.servlet.http.HttpSessionEvent;
|
import jakarta.servlet.http.HttpSessionEvent;
|
||||||
import jakarta.servlet.http.HttpSessionListener;
|
import jakarta.servlet.http.HttpSessionListener;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.config.interfaces.SessionsInterface;
|
||||||
|
import stirling.software.SPDF.config.interfaces.SessionsModelInterface;
|
||||||
import stirling.software.SPDF.config.security.UserUtils;
|
import stirling.software.SPDF.config.security.UserUtils;
|
||||||
|
import stirling.software.SPDF.model.SessionEntity;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomHttpSessionListener implements HttpSessionListener {
|
public class CustomHttpSessionListener implements HttpSessionListener, SessionsInterface {
|
||||||
|
|
||||||
private final SessionPersistentRegistry sessionPersistentRegistry;
|
private final SessionPersistentRegistry sessionPersistentRegistry;
|
||||||
|
|
||||||
|
@Value("${server.servlet.session.timeout:120s}") // TODO: Change to 30m
|
||||||
|
private Duration defaultMaxInactiveInterval;
|
||||||
|
|
||||||
public CustomHttpSessionListener(SessionPersistentRegistry sessionPersistentRegistry) {
|
public CustomHttpSessionListener(SessionPersistentRegistry sessionPersistentRegistry) {
|
||||||
super();
|
super();
|
||||||
this.sessionPersistentRegistry = sessionPersistentRegistry;
|
this.sessionPersistentRegistry = sessionPersistentRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SessionsModelInterface> getAllNonExpiredSessions() {
|
||||||
|
return sessionPersistentRegistry.getAllSessionsNotExpired().stream()
|
||||||
|
.map(session -> (SessionsModelInterface) session)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SessionsModelInterface> getAllNonExpiredSessionsBySessionId(
|
||||||
|
String sessionId) {
|
||||||
|
return sessionPersistentRegistry.getAllNonExpiredSessionsBySessionId(sessionId).stream()
|
||||||
|
.map(session -> (SessionsModelInterface) session)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SessionsModelInterface> getAllSessions() {
|
||||||
|
return new ArrayList<>(sessionPersistentRegistry.getAllSessions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSessionValid(String sessionId) {
|
||||||
|
List<SessionEntity> allSessions = sessionPersistentRegistry.getAllSessions();
|
||||||
|
// gib zurück ob ist expired
|
||||||
|
return allSessions.stream()
|
||||||
|
.anyMatch(
|
||||||
|
session ->
|
||||||
|
session.getSessionId().equals(sessionId) && !session.isExpired());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOldestNonExpiredSession(String sessionId) {
|
||||||
|
log.info("isOldestNonExpiredSession for sessionId: {}", sessionId);
|
||||||
|
List<SessionEntity> nonExpiredSessions =
|
||||||
|
sessionPersistentRegistry.getAllSessionsNotExpired();
|
||||||
|
return nonExpiredSessions.stream()
|
||||||
|
.min(Comparator.comparing(SessionEntity::getLastRequest))
|
||||||
|
.map(oldest -> oldest.getSessionId().equals(sessionId))
|
||||||
|
.orElse(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSessionLastRequest(String sessionId) {
|
||||||
|
sessionPersistentRegistry.refreshLastRequest(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sessionCreated(HttpSessionEvent se) {
|
public void sessionCreated(HttpSessionEvent se) {
|
||||||
|
HttpSession session = se.getSession();
|
||||||
|
if (session == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
SecurityContext securityContext = SecurityContextHolder.getContext();
|
SecurityContext securityContext = SecurityContextHolder.getContext();
|
||||||
if (securityContext == null) {
|
if (securityContext == null) {
|
||||||
log.debug("Security context is null");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Authentication authentication = securityContext.getAuthentication();
|
Authentication authentication = securityContext.getAuthentication();
|
||||||
if (authentication == null) {
|
if (authentication == null) {
|
||||||
log.info("Authentication is null");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Object principal = authentication.getPrincipal();
|
Object principal = authentication.getPrincipal();
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
log.info("Principal is null");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String principalName = UserUtils.getUsernameFromPrincipal(principal);
|
String principalName = UserUtils.getUsernameFromPrincipal(principal);
|
||||||
if (principalName == null || "anonymousUser".equals(principalName)) {
|
if (principalName == null) {
|
||||||
log.info("Principal is null or anonymousUser");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
session.setAttribute("principalName", principalName);
|
||||||
|
if ("anonymousUser".equals(principalName)) {
|
||||||
|
log.info("Principal is anonymousUser");
|
||||||
|
}
|
||||||
|
int allNonExpiredSessions = getAllNonExpiredSessions().size();
|
||||||
|
if (allNonExpiredSessions >= getMaxUserSessions()) {
|
||||||
|
log.info("Session {} Expired=TRUE", session.getId());
|
||||||
|
sessionPersistentRegistry.expireSession(session.getId());
|
||||||
|
sessionPersistentRegistry.removeSessionInformation(se.getSession().getId());
|
||||||
|
// if (allNonExpiredSessions > getMaxUserSessions()) {
|
||||||
|
// enforceMaxSessionsForPrincipal(principalName);
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
log.info("Session created: {}", principalName);
|
log.info("Session created: {}", principalName);
|
||||||
sessionPersistentRegistry.registerNewSession(se.getSession().getId(), principalName);
|
sessionPersistentRegistry.registerNewSession(se.getSession().getId(), principalName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enforceMaxSessionsForPrincipal(String principalName) {
|
||||||
|
// Alle aktiven Sessions des Benutzers über das gemeinsame Interface abrufen
|
||||||
|
List<SessionsModelInterface> userSessions =
|
||||||
|
getAllSessions().stream()
|
||||||
|
.filter(s -> !s.isExpired() && principalName.equals(s.getPrincipalName()))
|
||||||
|
.sorted(Comparator.comparing(SessionsModelInterface::getLastRequest))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
int maxAllowed = getMaxUserSessions();
|
||||||
|
if (userSessions.size() > maxAllowed) {
|
||||||
|
int sessionsToRemove = userSessions.size() - maxAllowed;
|
||||||
|
log.info(
|
||||||
|
"User {} has {} active sessions, removing {} oldest session(s).",
|
||||||
|
principalName,
|
||||||
|
userSessions.size(),
|
||||||
|
sessionsToRemove);
|
||||||
|
for (int i = 0; i < sessionsToRemove; i++) {
|
||||||
|
SessionsModelInterface sessionModel = userSessions.get(i);
|
||||||
|
// Statt auf die HttpSession zuzugreifen, rufen wir die Registry-Methoden auf,
|
||||||
|
// die die Session anhand der Session-ID invalidieren und entfernen.
|
||||||
|
sessionPersistentRegistry.expireSession(sessionModel.getSessionId());
|
||||||
|
sessionPersistentRegistry.removeSessionInformation(sessionModel.getSessionId());
|
||||||
|
log.info(
|
||||||
|
"Removed session {} for principal {}",
|
||||||
|
sessionModel.getSessionId(),
|
||||||
|
principalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sessionDestroyed(HttpSessionEvent se) {
|
public void sessionDestroyed(HttpSessionEvent se) {
|
||||||
sessionPersistentRegistry.expireSession(se.getSession().getId());
|
HttpSession session = se.getSession();
|
||||||
|
if (session == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionInformation sessionsInfo =
|
||||||
|
sessionPersistentRegistry.getSessionInformation(session.getId());
|
||||||
|
if (sessionsInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date lastRequest = sessionsInfo.getLastRequest();
|
||||||
|
int maxInactiveInterval = (int) defaultMaxInactiveInterval.getSeconds();
|
||||||
|
Instant now = Instant.now();
|
||||||
|
Instant expirationTime =
|
||||||
|
lastRequest.toInstant().plus(maxInactiveInterval, ChronoUnit.SECONDS);
|
||||||
|
|
||||||
|
if (now.isAfter(expirationTime)) {
|
||||||
|
sessionPersistentRegistry.expireSession(session.getId());
|
||||||
|
session.invalidate();
|
||||||
sessionPersistentRegistry.removeSessionInformation(se.getSession().getId());
|
sessionPersistentRegistry.removeSessionInformation(se.getSession().getId());
|
||||||
|
log.info("Session {} wurde Expired=TRUE", session.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerSession(HttpSession session) {
|
||||||
|
sessionCreated(new HttpSessionEvent(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSession(HttpSession session) {
|
||||||
|
sessionPersistentRegistry.expireSession(session.getId());
|
||||||
|
session.invalidate();
|
||||||
|
sessionPersistentRegistry.removeSessionInformation(session.getId());
|
||||||
|
log.info("Session {} wurde Expired=TRUE", session.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user