SpringBoot集成SpringSecurity(九设置用户最大登录数)

Posted 伍妖捌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot集成SpringSecurity(九设置用户最大登录数)相关的知识,希望对你有一定的参考价值。

前言

在项目中,可能会有这样的需求,只允许用户同一时间只能在一处登录。

实现

设置Session过期策略,创建SessionExpiredStrategy 类

@Component
public class SessionExpiredStrategy implements SessionInformationExpiredStrategy {
    @Autowired
    private SignInFailureHandler signInFailureHandler;

    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {
        UserDetails userDetails = (UserDetails) event.getSessionInformation().getPrincipal();
        String format = String.format("尊敬的[%s],您的账号在其他地方登录,请及时修改密码!", userDetails.getUsername());
        AuthenticationException exception = new AuthenticationServiceException(format);
        signInFailureHandler.onAuthenticationFailure(event.getRequest(), event.getResponse(), exception);
    }
}

设置Session失效策略,创建SessionInvalidStrategy类

@Component
public class SessionInvalidStrategy implements InvalidSessionStrategy {
    @Autowired
    private SessionRegistry sessionRegistry;

    @Override
    public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws
            IOException {
        sessionRegistry.removeSessionInformation(request.getRequestedSessionId());
        cancelCookie(request, response);
        Result result = Result.error().message("您当前的会话已超时,请重新登录!");
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().write(JsonUtil.toJsonString(result));
    }

    private void cancelCookie(HttpServletRequest request, HttpServletResponse response) {
        Cookie cookie = new Cookie("JSESSIONID", null);
        cookie.setMaxAge(0);
        cookie.setPath(this.getCookiePath(request));
        response.addCookie(cookie);
    }

    private String getCookiePath(HttpServletRequest request) {
        String contextPath = request.getContextPath();
        return contextPath.length() > 0 ? contextPath : "/";
    }
}

在退出登录时,删除Session信息,创建SignOutHandler类

@Component
public class SignOutHandler implements LogoutHandler {
    @Autowired
    private SessionRegistry sessionRegistry;

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        sessionRegistry.removeSessionInformation(request.getSession().getId());
    }
}

SpringSecurityConfig中添加以下代码
注入需要的Bean

	@Autowired
    SignOutHandler signOutHandler;

    @Autowired
    SessionExpiredStrategy sessionExpiredStrategy;

    @Autowired
    SessionInvalidStrategy sessionInvalidStrategy;

    @Bean
    SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

退出时删除Session

	http.logout()
		.addLogoutHandler(signOutHandler)
		.logoutSuccessHandler(signOutSuccessHandler);
	http.sessionManagement()
		.invalidSessionStrategy(sessionInvalidStrategy)
		.maximumSessions(1)
		.expiredSessionStrategy(sessionExpiredStrategy)
		.sessionRegistry(sessionRegistry());

以上是关于SpringBoot集成SpringSecurity(九设置用户最大登录数)的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot项目启动后访问任意接口都会跳转到一个莫名其妙的login登录页面

SpringSecurity解决跨域问题,在SpringBoot整合SprinSecurity中如何用前后端分离Ajax登录,Ajax登录返回状态200还是近error

001.camunda入门(springboot集成篇)

在邮递员上发布请求但不在浏览器中(代码状态:415) - Spring Boot,thymeleaf

springboot集成ES,以及应用

SpringBoot集成Kafka