package com.github.kazuki43zoo.web.security;
import com.github.kazuki43zoo.domain.model.account.AccountAuthenticationHistory;
import com.github.kazuki43zoo.domain.model.account.AuthenticationType;
import com.github.kazuki43zoo.domain.service.security.AuthenticationSharedService;
import com.github.kazuki43zoo.domain.service.security.CustomAuthenticationDetails;
import com.github.kazuki43zoo.domain.service.security.CustomUserDetails;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.dozer.Mapper;
import org.springframework.context.event.EventListener;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.session.SessionFixationProtectionEvent;
import org.springframework.security.web.session.HttpSessionDestroyedEvent;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
@Component
@Aspect
public class SessionEventListeners {
private static final String HANDLE_LOGOUT_KEY = SecurityContextLogoutHandler.class.getName()
.concat(".logout");
@Inject
AuthenticationSharedService authenticationSharedService;
@Inject
Mapper beanMapper;
@EventListener
@Transactional
public void onHttpSessionDestroyed(final HttpSessionDestroyedEvent event) {
final Boolean isHandleLogout = (Boolean) event.getSession().getAttribute(HANDLE_LOGOUT_KEY);
if (isHandleLogout != null && isHandleLogout) {
return;
}
final List<SecurityContext> securityContexts = event.getSecurityContexts();
for (final SecurityContext securityContext : securityContexts) {
final CustomUserDetails userDetails = CustomUserDetails.getInstance(securityContext.getAuthentication());
final AccountAuthenticationHistory authenticationHistory = beanMapper.map(securityContext.getAuthentication().getDetails(), AccountAuthenticationHistory.class);
authenticationSharedService.createAuthenticationSuccessHistory(userDetails.getAccount(), authenticationHistory, AuthenticationType.SESSION_TIMEOUT);
}
}
@Before(value = "execution(* org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.logout(..))")
public void handleLogout(final JoinPoint joinPoint) {
final HttpServletRequest request = HttpServletRequest.class.cast(joinPoint.getArgs()[0]);
final HttpSession session = request.getSession(false);
if (session != null) {
session.setAttribute(HANDLE_LOGOUT_KEY, true);
}
}
@EventListener
public void onSessionFixationProtection(final SessionFixationProtectionEvent event) {
final CustomAuthenticationDetails authenticationDetails = CustomAuthenticationDetails.class.cast(event.getAuthentication().getDetails());
authenticationDetails.setSessionId(event.getNewSessionId());
}
}