spring-security Spring Security -公共页重定向到具有无效会话ID的登录

rsaldnfx  于 2022-11-11  发布在  Spring
关注(0)|答案(2)|浏览(226)

我遇到了一个问题,当你已经有一个不再有效的SessionID时,公共URL在Spring安全中不起作用。
示例:
我有一个用户注册页面,并给它一个permitAll访问权限,如下所示:

http.authorizeRequests().antMatchers("/register**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().loginPage("/login").permitAll();

对于我的会话设置,我有:

http.sessionManagement().invalidSessionUrl("/login?logoutcause=sessiontimeout");
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
http.sessionManagement().sessionAuthenticationErrorUrl("/login");
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
http.sessionManagement().sessionFixation().newSession();

如果我有一个来自上一个会话的sessionID,它可能是一个旧的和无效的,并且我点击了Route“/register”,Spring会抱怨无效的会话ID,并将我重定向到“/login”。
只是提一下:其他一切,如登录,资源管理,受保护的url和注销都在配置中按预期工作。

**复制此内容:**使用Spring中的Redis会话管理。进入登录页面,用控制台刷新redis数据库。直接在浏览器中访问注册页面-〉重定向到登录,因为会话ID无效。

o.s.s.w.s.SessionManagementFilter        : Requested session ID 8ad2e166-bc21-4646-8390-ad8d1043baec is invalid.
w.s.SimpleRedirectInvalidSessionStrategy : Starting new session (if required) and redirecting to '/login?logoutcause=sessiontimeout'
o.s.s.w.DefaultRedirectStrategy          : Redirecting to '/login?logoutcause=sessiontimeout'

为什么Spring还要检查具有“公共”访问权限的路由的会话ID?
下一步:如果我完全禁用了路由本身的任何安全检查,不幸的是,所需的资源(如js和css资产)会触发相同的行为,要么我被重定向到登录,要么资产根本就不会被交付(都没有选项:D)

@Override
public void configure(WebSecurity web) throws Exception {
  web.ignoring().antMatchers("/register/**");
  super.configure(web);
}

我的解决方案和解决方法

我禁用了以下配置,它解决了我的所有问题

// DISABLED
// http.sessionManagement().invalidSessionUrl("/login?logoutcause=sessiontimeout");

我的问题

这可能不是最好的方法,对吗?什么是更好和更安全的方法来做它。请帮助我理解为什么这是这样做的Spring,或我配置了错误的方式。

6jygbczu

6jygbczu1#

我通过添加以下配置解决了相同的问题:

.antMatchers("/login-invalid").permitAll()
sigwle7e

sigwle7e2#

我也遇到了同样的问题,解决方法如下。

0.先决条件

  • JDK17
  • Spring Boot2.7

1.创建自定义InvalidSessionStrategy

@Component
public class MyInvalidSessionStrategy implements InvalidSessionStrategy {

  private final InvalidSessionStrategy simpleRedirectStrategy;

  private final InvalidSessionStrategy requestedUrlRedirectStrategy;

  private final HandlerMappingIntrospector handlerMappingIntrospector;

  public MyInvalidSessionStrategy(HandlerMappingIntrospector handlerMappingIntrospector) {
    this.simpleRedirectInvalidSessionStrategy = new SimpleRedirectInvalidSessionStrategy("/login?logoutcause=sessiontimeout");
    this.requestedUrlRedirectStrategy = new RequestedUrlRedirectInvalidSessionStrategy();
    this.handlerMappingIntrospector = handlerMappingIntrospector;
  }

  @Override
  public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
      throws IOException {

    var matcher = new MvcRequestMatcher(handlerMappingIntrospector, "/register/**");

    if (matcher.matches(request))) {      
      requestedUrlRedirectStrategy.onInvalidSessionDetected(request, response);
    } else {
      simpleRedirectStrategy.onInvalidSessionDetected(request, response);
    }
  }
}

2.配置spring-securiry并注册自定义InvalidSessionStrategy

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

  @Bean
  SecurityFilterChain filterChain(
      HttpSecurity http,
      MyInvalidSessionStrategy invalidSessionStrategy)
      throws Exception {

    return http
      .login(...)
      .logout(...)
      .sessionManagement(
        configurer -> configurer
          .invalidSessionStrategy(invalidSessionStrategy))
      .build();
  }
}

相关问题