zoukankan      html  css  js  c++  java
  • SpringBoot的Session并发控制

    ⒈是什么?

      即控制业务系统中一个用户只能有一个Session

    ⒉解决方案

      1.当这个用户在其它地方登录的时候,把之前的Session失效掉。

     1 package cn.coreqi.security.config;
     2 
     3 import cn.coreqi.security.Filter.SmsCodeFilter;
     4 import cn.coreqi.security.Filter.ValidateCodeFilter;
     5 import cn.coreqi.security.session.CoreqiExpiredSessionStrategy;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.context.annotation.Bean;
     8 import org.springframework.context.annotation.Configuration;
     9 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    10 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    11 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    12 import org.springframework.security.crypto.password.PasswordEncoder;
    13 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    14 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    15 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    16 
    17 @Configuration
    18 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    19 
    20     @Autowired
    21     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
    22 
    23     @Autowired
    24     private AuthenticationFailureHandler coreqiAuthenticationFailureHandler;
    25 
    26     @Autowired
    27     private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
    28 
    29     @Bean
    30     public PasswordEncoder passwordEncoder(){
    31         return NoOpPasswordEncoder.getInstance();
    32     }
    33 
    34 
    35     @Override
    36     protected void configure(HttpSecurity http) throws Exception {
    37         ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
    38         validateCodeFilter.setAuthenticationFailureHandler(coreqiAuthenticationFailureHandler);
    39 
    40         SmsCodeFilter smsCodeFilter = new SmsCodeFilter();
    41 
    42 
    43         //http.httpBasic()    //httpBasic登录 BasicAuthenticationFilter
    44         http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class)    //加载用户名密码过滤器的前面
    45                 .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)    //加载用户名密码过滤器的前面
    46                 .formLogin()    //表单登录 UsernamePasswordAuthenticationFilter
    47                     .loginPage("/coreqi-signIn.html")  //指定登录页面
    48                     //.loginPage("/authentication/require")
    49                     .loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
    50                     .successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
    51                     .failureHandler(coreqiAuthenticationFailureHandler) //自己体会把
    52                 .and()
    53                 .sessionManagement()
    54                     .invalidSessionUrl("session/invalid")    //session过期后跳转的URL
    55                     .maximumSessions(1) //配置最大的Session数量,即同一个用户后面登录所产生的Session之前登录所产生的Session给失效掉
    56                     .expiredSessionStrategy(new CoreqiExpiredSessionStrategy())
    57                 .and()
    58                 .and()
    59                 .authorizeRequests()    //对授权请求进行配置
    60                     .antMatchers("/coreqi-signIn.html","/code/image","/session/invalid").permitAll() //指定登录页面不需要身份认证
    61                     .anyRequest().authenticated()  //任何请求都需要身份认证
    62                     .and().csrf().disable()    //禁用CSRF
    63                 .apply(smsCodeAuthenticationSecurityConfig);
    64             //FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
    65     }
    66 }
     1 package cn.coreqi.security.session;
     2 
     3 import org.springframework.security.web.session.SessionInformationExpiredEvent;
     4 import org.springframework.security.web.session.SessionInformationExpiredStrategy;
     5 
     6 import javax.servlet.ServletException;
     7 import java.io.IOException;
     8 
     9 public class CoreqiExpiredSessionStrategy implements SessionInformationExpiredStrategy {
    10     @Override
    11     public void onExpiredSessionDetected(SessionInformationExpiredEvent sessionInformationExpiredEvent) throws IOException, ServletException {
    12         sessionInformationExpiredEvent.getResponse().setContentType("application/json;charset=UTF-8");
    13         sessionInformationExpiredEvent.getResponse().getWriter().write("并发登录!");
    14     }
    15 }

      2.当这个用户已经登陆了,禁止在其它地方登录。

     1 package cn.coreqi.security.config;
     2 
     3 import cn.coreqi.security.Filter.SmsCodeFilter;
     4 import cn.coreqi.security.Filter.ValidateCodeFilter;
     5 import cn.coreqi.security.session.CoreqiExpiredSessionStrategy;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.context.annotation.Bean;
     8 import org.springframework.context.annotation.Configuration;
     9 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    10 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    11 import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    12 import org.springframework.security.crypto.password.PasswordEncoder;
    13 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    14 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    15 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    16 
    17 @Configuration
    18 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    19 
    20     @Autowired
    21     private AuthenticationSuccessHandler coreqiAuthenticationSuccessHandler;
    22 
    23     @Autowired
    24     private AuthenticationFailureHandler coreqiAuthenticationFailureHandler;
    25 
    26     @Autowired
    27     private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
    28 
    29     @Bean
    30     public PasswordEncoder passwordEncoder(){
    31         return NoOpPasswordEncoder.getInstance();
    32     }
    33 
    34 
    35     @Override
    36     protected void configure(HttpSecurity http) throws Exception {
    37         ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
    38         validateCodeFilter.setAuthenticationFailureHandler(coreqiAuthenticationFailureHandler);
    39 
    40         SmsCodeFilter smsCodeFilter = new SmsCodeFilter();
    41 
    42 
    43         //http.httpBasic()    //httpBasic登录 BasicAuthenticationFilter
    44         http.addFilterBefore(smsCodeFilter, UsernamePasswordAuthenticationFilter.class)    //加载用户名密码过滤器的前面
    45                 .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)    //加载用户名密码过滤器的前面
    46                 .formLogin()    //表单登录 UsernamePasswordAuthenticationFilter
    47                     .loginPage("/coreqi-signIn.html")  //指定登录页面
    48                     //.loginPage("/authentication/require")
    49                     .loginProcessingUrl("/authentication/form") //指定表单提交的地址用于替换UsernamePasswordAuthenticationFilter默认的提交地址
    50                     .successHandler(coreqiAuthenticationSuccessHandler) //登录成功以后要用我们自定义的登录成功处理器,不用Spring默认的。
    51                     .failureHandler(coreqiAuthenticationFailureHandler) //自己体会把
    52                 .and()
    53                 .sessionManagement()
    54                     .invalidSessionUrl("session/invalid")    //session过期后跳转的URL
    55                     .maximumSessions(1) //配置最大的Session数量,即同一个用户后面登录所产生的Session之前登录所产生的Session给失效掉
    56                     .maxSessionsPreventsLogin(true) //当一个用户的Session数量达到最大数量以后,阻止后面的登陆行为
    57                 .expiredSessionStrategy(new CoreqiExpiredSessionStrategy())
    58                 .and()
    59                 .and()
    60                 .authorizeRequests()    //对授权请求进行配置
    61                     .antMatchers("/coreqi-signIn.html","/code/image","/session/invalid").permitAll() //指定登录页面不需要身份认证
    62                     .anyRequest().authenticated()  //任何请求都需要身份认证
    63                     .and().csrf().disable()    //禁用CSRF
    64                 .apply(smsCodeAuthenticationSecurityConfig);
    65             //FilterSecurityInterceptor 整个SpringSecurity过滤器链的最后一环
    66     }
    67 }
  • 相关阅读:
    酒里放茶,醉,未遂。
    利用自定义事件实现不同窗体间的通讯 Delphi篇
    主题:CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\***.dll”错误处理
    delphi點擊窗體最小化,關閉按鈕時的托盤圖標設置
    delphi制作程序啟動歡迎窗體
    那年 那雪
    DOL魔盘解决方案
    专家解密“艳照门”背后三大安全陷阱
    jQuery获取Select选择的Text和 Value(转)
    技术列传 guava cache
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/10658216.html
Copyright © 2011-2022 走看看