[英]Spring Security - Public pages redirected to login with invalid session id
我遇到了一个问题,当您已经有一个不再有效的 SessionID 时,公共 url 在 Spring 安全性中不起作用。
例子:
我有用户注册页面,并给了它一个 permitAll 访问权限,如下所示:
http.authorizeRequests().antMatchers("/register**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().loginPage("/login").permitAll();
对于我的 Session 设置,我有:
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();
如果我有一个来自之前 session 的 sessionID,这可能是一个旧且无效的,并且我点击了路由“/register”,spring 抱怨无效的 Z21D6F40CFB511982E4424E0E2 并将我重定向到“0/9557”。
顺便提一下:其他一切,如登录、资源管理、受保护的 url 和注销,都按配置正常工作。
重现此:在 Spring 中使用 Redis-Session 管理。 进入登录页面,使用控制台刷新 redis db。 直接在浏览器中访问注册页面 -> 由于 session 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 甚至检查 session 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 会这样做,或者我配置错误的方式。
我通过添加以下配置解决了同样的问题:
.antMatchers("/login-invalid").permitAll()
我有同样的问题,并解决如下。
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);
}
}
}
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.