• SpringSecurity(九): 自定义Session 会话超时处理逻辑


    默认情况下,当 session(默认30分钟) 失效后会请求回认证页面。我们可以自定义 session 失效后,响应不同的结果。
     
    自定义CustomInvalidSessionStrategy类实现InvalidSessionStrategy
    /**
     * 当session失效后的处理逻辑
     */
    @Component("customInvalidSessionStrategy")
    public class CustomInvalidSessionStrategy implements InvalidSessionStrategy {
        @Override
        public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException {
            // 1.将浏览器的sessionid清除,不关闭浏览器cookie不会被删除,一直请求都提示:Session失效
            cancelCookie(request, response);
            //2.当session失效后响应json数据给前端
            Result result = new Result().build(HttpStatus.UNAUTHORIZED.value(), "登录超时,请重新登录");
            String s = result.toJsonString();
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(s);
    
        }
    
    
        protected void cancelCookie(HttpServletRequest request, HttpServletResponse response) {
            Cookie cookie = new Cookie("JSESSIONID", null);
            cookie.setMaxAge(0);
            cookie.setPath(getCookiePath(request));
            response.addCookie(cookie);
        }
    
        private String getCookiePath(HttpServletRequest request) {
            String contextPath = request.getContextPath();
            return contextPath.length() > 0 ? contextPath : "/";
        }
    }

    在安全配置类SpringSecurityConfig中注入自定义CustomInvalidSessionStrategy实例并进行配置

     @Autowired
        CustomInvalidSessionStrategy customInvalidSessionStrategy;
        /**
         * 记住我 功能
         */
        @Autowired
        DataSource dataSource;
        @Bean
        public JdbcTokenRepositoryImpl jdbcTokenRepository(){
            JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
            jdbcTokenRepository.setDataSource(dataSource);
            // 是否启动时自动创建表,第一次启动创建就行,后面启动把这个注释掉,不然报错已存在表
            //jdbcTokenRepository.setCreateTableOnStartup(true);
            return jdbcTokenRepository;
        }
    
        /**
         * 资源权限配置(过滤器链):
         * 1、被拦截的资源
         * 2、资源所对应的角色权限
         * 3、定义认证方式:httpBasic 、httpForm
         * 4、定制登录页面、登录请求地址、错误处理方式
         * 5、自定义 spring security 过滤器
         *
         * @param http
         * @throws Exception
         */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //http.httpBasic()//采用httpBasic 认证方式
            /*http.formLogin()
                    .loginPage("/login/page")// 交给 /login/page 响应认证(登录)页面
                    .loginProcessingUrl("/login/form")  // 登录表单提交处理Url, 默认是 /login
                    .usernameParameter("name") // 默认用户名的属性名是 username
                    .passwordParameter("pwd") // 默认密码的属性名是 password
                    .and()
                    .authorizeRequests()//认证请求
                    .antMatchers("/login/page").permitAll()//自定义登录页不需要认证
                    .anyRequest().authenticated();// 所有进入应用的HTTP请求都要进行认证*/
    
            http
                    .addFilterBefore(imageVerifyCodeValidateFilter, UsernamePasswordAuthenticationFilter.class)//将校验过滤器 imageCodeValidateFilter 添加到 UsernamePasswordAuthenticationFilter 前面
                    .addFilterBefore(smsVerifyCodeValidateFilter,UsernamePasswordAuthenticationFilter.class)//将校验过滤器 smsVerifyCodeValidateFilter 添加到 UsernamePasswordAuthenticationFilter 前面
                    .formLogin()
                    .loginPage(securityProperties.getLoginPage())// 交给 /login/page 响应认证(登录)页面
                    .loginProcessingUrl(securityProperties.getLoginProcessingUrl())  // 登录表单提交处理Url, 默认是 /login
                    .usernameParameter(securityProperties.getUsernameParameter()) // 默认用户名的属性名是 username
                    .passwordParameter(securityProperties.getPasswordParameter()) // 默认密码的属性名是 password
                    .successHandler(customAuthenticationSuccessHandler)//自定义认证成功处理器
                    .failureHandler(customAuthenticationFailureHandler)//自定义认证失败处理器
                    .and()
                    .authorizeRequests()//认证请求
                    .antMatchers(securityProperties.getLoginPage(),securityProperties.getMobilePage(),securityProperties.getImageCodeUrl(),securityProperties.getMobileCodeUrl()).permitAll()//自定义登录页不需要认证,生成图片验证码,发送短信获取验证码也不需要验证
                    .anyRequest().authenticated()// 所有进入应用的HTTP请求都要进行认证
                    .and()
                    .rememberMe()//记住我功能
                    .tokenRepository(jdbcTokenRepository())//保存登录信息
                    .tokenValiditySeconds(securityProperties.getTokenValiditySeconds())//记住我有效时长一周
                    .and()
                    .sessionManagement()//session会话管理
                    .invalidSessionStrategy(customInvalidSessionStrategy)//当session失效后的处理类
            ;
    
            // 将手机相关的配置绑定过滤器链上
            http.apply(mobileAuthenticationConfig);
        }

    测试:

     完整代码地址:https://gitee.com/zhechaochao/security-parent.git

  • 相关阅读:
    ExtJS 基础解析之【Ext.Window】
    螺旋队列算法分析 (转载)
    字符串NSString中去掉空格
    iOSCocos2d使用Zwoptex生成plist文件
    获取网上流视频总时长和当前播放时长
    popToViewController导航条跳转的用法
    iOS: Device token and registerForRemoteNotificationTypes, didReceiveRemoteNotification
    UILabel的详细使用及特殊效果
    UITextView使用sizeWithFont:计算自适应文本高度
    iPhone开放播放gif动画
  • 原文地址:https://www.cnblogs.com/yscec/p/14319828.html
Copyright © 2020-2023  润新知