package com.ycl.jxkg.config.spring.security; import com.ycl.jxkg.base.SystemCode; import com.ycl.jxkg.constants.CaffeineConstant; import com.ycl.jxkg.utils.CaffeineUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; import java.util.Objects; /** * @author 29443 * @date 2022/4/4 */ @Slf4j public class SessionFilter extends BasicAuthenticationFilter { @Autowired private CaffeineUtil caffeineUtil; public SessionFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 检查请求中是否有security设置的认证信息。没有的话本Filter不做处理 SecurityContextImpl securityContext = (SecurityContextImpl) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); if (Objects.isNull(securityContext)) { chain.doFilter(request, response); return; } // 有的话验证 Authentication authentication = securityContext.getAuthentication(); User authUser = (User) authentication.getPrincipal(); // 检查这个用户对应的sessionId是否和登录时的sessionId相等 String loginSessionId = (String) caffeineUtil.get(CaffeineConstant.AUTH, authUser.getUsername()); if (! request.getSession().getId().equals(loginSessionId)) { log.warn("检测到同一账号两个浏览器登录"); RestUtil.response(response, SystemCode.UNAUTHORIZED.getCode(), "当前登录已失效"); } else { chain.doFilter(request, response); } } }