zoukankan      html  css  js  c++  java
  • 2536-springsecurity系列--关于session管理1

    版本信息

    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.14.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <version>1.5.14.RELEASE</version>
        <!--实际里面spring-security-web的版本是4.2.7-->
    </dependency>
    
    
    
    
    

    在ss中基本的session管理

    • session无效处理
    • session过期处理
    • 并发登录处理
    • 限制同一用户重复登录和顶号
    
        // 配置session相关
        // CustomSecurityProperties是自定义的常量参数类
        private void configSession(HttpSecurity http) throws Exception {
            http.sessionManagement()
                    .invalidSessionStrategy(invalidSessionStrategy) //session无效处理策略
                    .invalidSessionUrl(CustomSecurityProperties.invalidSessionUrl)  
                    .maximumSessions(1)  //同一用户最大session数
                    .maxSessionsPreventsLogin(false) //达到最大数禁止登录(预防并发登录)
                    .expiredSessionStrategy(sessionInformationExpiredStrategy) //session过期处理策略
                    .expiredUrl(CustomSecurityProperties.expiredSessionUrl);
        }
    
    

    并发登录处理

    例如用户在两台电脑上登录,并在两台电脑上办公,可设置maximumSessions值为2,这样springsecurity在管理session时会对该用户保持两个有效的session。

    限制同一用户重复登录和顶号

    例如要求用户最多只能在一台电脑上登录,并且另一台电脑登录会顶掉之前的登录信息。
    maximumSessions设置为1
    maxSessionsPreventsLogin设置为false

    例如要求用户最多只能在一台电脑上登录,并且另一台电脑登录会提示不可重复登录。
    maximumSessions设置为1
    maxSessionsPreventsLogin设置为true

    session无效处理和session过期处理

    简单的处理,只是进行url跳转,配置invalidSessionUrl和expiredUrl两个参数即可。
    如果需要记录session无效或过期时的用户信息、日志等,需要自定义实现类InvalidSessionStrategy和SessionInformationExpiredStrategy

    自定义处理

    自定义三个类
    AbstractSessionStrategy
    CustomExpiredSessionStrategy
    CustomInvalidSessionStrategy
    

    在config类中进行配置

        /**
         * 配置sec的session失效策略
         * 配置给sessionManagement
         */
        @Bean
        @ConditionalOnMissingBean(InvalidSessionStrategy.class)
        public InvalidSessionStrategy invalidSessionStrategy() {
            return new CustomInvalidSessionStrategy(CustomSecurityProperties.invalidSessionUrl);
        }
    
        /**
         * 配置sec的session过期策略
         * 配置给sessionManagement
         */
        @Bean
        @ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
        public SessionInformationExpiredStrategy sessionInformationExpiredStrategy() {
            return new CustomExpiredSessionStrategy(CustomSecurityProperties.invalidSessionUrl);
        }
    
    

    三个实现类的代码:

    AbstractSessionStrategy

    
    import com.company.testss12.support.RetVO;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.HttpStatus;
    import org.springframework.security.web.DefaultRedirectStrategy;
    import org.springframework.security.web.RedirectStrategy;
    import org.springframework.security.web.util.UrlUtils;
    import org.springframework.util.Assert;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @author starmoon1994
     */
    public class AbstractSessionStrategy {
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
        /**
         * 跳转的url
         */
        private String destinationUrl;
        /**
         * 重定向策略
         */
        private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
        /**
         * 跳转前是否创建新的session
         */
        private boolean createNewSession = true;
    
        private ObjectMapper objectMapper = new ObjectMapper();
    
        /**
         */
        public AbstractSessionStrategy(String invalidSessionUrl) {
            Assert.isTrue(UrlUtils.isValidRedirectUrl(invalidSessionUrl), "url must start with '/' or with 'http(s)'");
            this.destinationUrl = invalidSessionUrl;
        }
    
        protected void onSessionInvalid(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
            logger.info("onSessionInvalid IP:{}   URI:{}", request.getRemoteHost(), request.getRequestURI());
    
            if (createNewSession) {
                request.getSession();
            }
    
            String sourceUrl = request.getRequestURI();
            String targetUrl;
    
            if (StringUtils.endsWithIgnoreCase(sourceUrl, ".html")) {
                targetUrl = destinationUrl;//+".html";
                logger.info("session失效,跳转到" + targetUrl);
                redirectStrategy.sendRedirect(request, response, targetUrl);
            } else {
                String message = "session已失效,请重新登录";
                if (isConcurrency()) {
                    message = message + ",有可能是并发登录导致的";
                }
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setContentType("application/json;charset=UTF-8");
    
                RetVO retVO = new RetVO();
                retVO.setMsg(message);
                response.getWriter().write(objectMapper.writeValueAsString(retVO));
            }
    
        }
    
        /**
         * session失效是否是并发导致的
         */
        protected boolean isConcurrency() {
            return false;
        }
    
        /**
         * Determines whether a new session should be created before redirecting (to
         * avoid possible looping issues where the same session ID is sent with the
         * redirected request). Alternatively, ensure that the configured URL does
         * not pass through the {@code SessionManagementFilter}.
         *
         * @param createNewSession defaults to {@code true}.
         */
        public void setCreateNewSession(boolean createNewSession) {
            this.createNewSession = createNewSession;
        }
    
    }
    
    
    

    CustomExpiredSessionStrategy

    
    import org.springframework.security.web.session.SessionInformationExpiredEvent;
    import org.springframework.security.web.session.SessionInformationExpiredStrategy;
    
    import java.io.IOException;
    
    /**
     * session失效策略
     */
    public class CustomExpiredSessionStrategy extends AbstractSessionStrategy implements SessionInformationExpiredStrategy {
    
        public CustomExpiredSessionStrategy(String invalidSessionUrl) {
            super(invalidSessionUrl);
        }
    
        @Override
        public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {
            onSessionInvalid(event.getRequest(), event.getResponse());
        }
    
        @Override
        protected boolean isConcurrency() {
            return true;
        }
    
    }
    
    

    CustomInvalidSessionStrategy

    
    import org.springframework.security.web.session.InvalidSessionStrategy;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @author starmoon1994
     */
    public class CustomInvalidSessionStrategy extends AbstractSessionStrategy implements InvalidSessionStrategy {
    
        public CustomInvalidSessionStrategy(String invalidSessionUrl) {
            super(invalidSessionUrl);
        }
    
    
        @Override
        public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
                throws IOException {
            onSessionInvalid(request, response);
        }
    
    }
    
    

    完整项目工程参考

    https://github.com/starmoon1994/springsecurity-collection

  • 相关阅读:
    (二)unittest之跳过测试和预期失败的用例
    (一)基本使用
    python从入门到入魔
    (十)中断测试
    (九)进程测试
    (八)安装、卸载与升级更新测试
    (七)功能测试
    (六)内存分析,待补充
    (五)跑Monkey过程中出现的ANR问题分析
    (四)一种精准monkey测试的方法
  • 原文地址:https://www.cnblogs.com/starmoon1994/p/9362325.html
Copyright © 2011-2022 走看看