Spring Security学习之会话管理

本文介绍了Spring Security的会话管理,包括会话的概念、防御固定会话攻击、会话过期处理和会话并发控制。Spring Security提供多种策略防御会话固定攻击,如newSession、migrateSession等,默认采用migrateSession。会话过期处理可以通过配置指定URL或自定义策略。会话并发控制可通过maximumSessions设置最大并发会话数,通过HttpSessionEventPublisher处理监听事件。
摘要由CSDN通过智能技术生成

概念

会话:session,对于无状态的HTTP 实现用户状态可维持的一种解决方案。

  • HTTP的无状态特点使得用户给与在服务器交互的过程中,每个请求间没有关联性,即用户的访问没有身份记录,站点无法为用户提供个性化服务。session的诞生解决这个问题(利用session保存用户身份)

  • 服务器通过与用户约定,每个请求都会携带一个id类的信息,使得不用请求间有了关联;id也方便与用户绑定,就可把不同请求归类到同一用户

  • 基于此方案,为了使同一个用户的每个请求都携带一个id,需要一个载体去存储这个id,即cookie

    • 当用户首次访问系统时,系统为该用户生成一个sessionId,并添加到cookie中,那么在这个用户的会话session期间,每个请求都会自动携带cookie,由此系统可轻易识别出这是哪个用户的请求

    • 但是有时候用户可能处于隐私或者安全考虑,会在浏览器中禁掉cookie,这个时候基于cookie实现的sessionId无法正常使用

    • 有些系统使用重写URL来兼容禁用cookie的浏览器,但是容易遭到黑客攻击 http://xxx.com;jsessionid=xxxx

      • 黑客只需要一次访问系统,将系统生成的sessionId提取并拼凑在URL上,然后将该URL发送给一些取得信任的用户,用户只要在session有效期通过url登录,该sessionId就会绑定到用户的身份,黑客也可享有同样的会话状态,完全不需要用户名和密码,即会话攻击

  • 一个账户能多处同时登录不是一个好的策略,容易被他人劫持session会话后冒充普通用户访问系统

  • SS提供了完善的会话管理功能

    • 会话固定攻击

    • 会话超时检测

    • 会话并发控制

防御固定会话攻击

原理很简单,在用户登录之后重新生成新的session即可(这样就避免用户通过钓鱼链接访问登录系统后,因为绑定钓鱼的session导致钓鱼有了普通用户的身份,无需登录即可访问系统;管他什么链接登进来的,重新生成session,这样旧session被替换掉,相当于黑客与被监测用户失联)

  1. SS框架的WebSecurityConfigurerAdapter中getHttp方法,使用sessionManagement会话管理器对session进行了配置

    1. SS框架支持四中防御会话固定攻击策略

      1. none:不做任何变动,登录后沿用旧session

      2. newSession:登录之后创建一个新的session

      3. migrateSession:登录后创建一个新的session,并将旧的session中的数据复制过来

      4. changeSessionId:不创建新的session,使用由Servlet容器提供的会话固定保护

    2. SS框架默认使用migrateSession策略

    3. 也可根据需要重写configure方法,进行手动配置策略(WebSecurityConfig方法集成WebSecurityConfigurerAdapter类)

  2. 在SS中,即使没有配置,也不用担心固定会话攻击,因为SS的HTTP防火墙(StrictHttpFirewall类)会拦截不合法的URL,当试图访问携带session的URL时,会被SS框架重定向到提示500的错误页(没登录的时候使用session访问就会直接报错)

//WebSecurityConfigurerAdapter

protected final HttpSecurity getHttp() throws Exception {
    if (this.http != null) {
        return this.http;
    } else {
        AuthenticationEventPublisher eventPublisher = this.getAuthenticationEventPublisher();
        this.localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
        AuthenticationManager authenticationManager = this.authenticationManager();
        this.authenticationBuilder.parentAuthenticationManager(authenticationManager);
        Map<Class<?>, Object> sharedObjects = this.createSharedObjects();
        this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects);
        if (!this.disableDefaults) {
            // 使用sessionManagement方法进行会话管理
            ((HttpSecurity)((DefaultLoginPageConfigurer)((HttpSecurity)((HttpSecurity)((HttpSecurity)((HttpSecurity)((HttpSecurity)((HttpSecurity)((HttpSecurity)((HttpSecurity)this.http.csrf().and()).addFilter(new WebAsyncManagerIntegrationFilter()).exceptionHandling().and()).headers().and()).sessionManagement().and()).securityContext().and()).requestCache().and()).anonymous().and()).servletApi().and()).apply(new DefaultLoginPageConfigurer())).and()).logout();
            ClassLoader classLoader = this.context.getClassLoader();
            List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);
            Iterator var6 = defaultHttpConfigurers.iterator();


            while(var6.hasNext()) {
                AbstractHttpConfigurer configurer = (AbstractHttpConfigurer)var6.next();
                this.http.apply(configurer);
            }
        }


        this.configure(this.http);
        return this.http;
    }
}

自定义会话管理

配置会话管理的类型为

  1. none:不做任何变动,登录后沿用旧session

  2. newSession:登录之后创建一个新的session

  3. migrateSession:登录后创建一个新的session,并将旧的session中的数据复制过来

  4. changeSessionId:不创建新的session,使用由Servlet容器提供的会话固定保护

                  // 配置会话管理器
                .sessionManagement()
                // 会话固定攻击防御策略 fixation会话固定
                    .sessionFixation().none()
@EnableWebSecurity // 自带@Configuration,此处无需再加@Configutaion注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsServiceImpl userDetailsServiceImpl;

    /**
     * 建立身份认证方式 AuthenticationManagerBuilder创建一个AuthenticationManager用于进行身份认证
     * 包括:内存验证、LDAP验证、基于JDBC的验证、添加UserDetailsService、添加AuthenticationProvider
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 使用密文,加密方式使用自定义的passwordEncoder类
        auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(myPasswordEncoder());
    }


    /**
     * 开启认证 配置需要认证的url
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) thro
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值