min*_*int 7 java spring-security unauthorized session-cookies spring-boot
我的申请遇到了一些问题。我们使用 Spring Boot 2.4.10 和 Spring Security 5.4.8。我们使用 cookie 与应用程序交互。
我们有一个存储在src/main/resources其中的前端应用程序,其中包括连接到/api/v1/notification.
application.properties文件:
# cookie-related settings
server.servlet.session.cookie.name=mySessionCookie
server.servlet.session.cookie.path=/
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
Run Code Online (Sandbox Code Playgroud)
# cookie-related settings
server.servlet.session.cookie.name=mySessionCookie
server.servlet.session.cookie.path=/
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
Run Code Online (Sandbox Code Playgroud)
当没有用户登录时,前端会尝试定期访问 websocket 端点以打开连接。
第一个api/v1/notification结束重定向到/error端点,该端点返回HttpServletResponse带有“Set-Cookie”标头(我认为这可能是在第一个请求中设置的匿名 cookie?)和401状态。我无法改变这种行为。
以下请求api/v1/notification在标头中使用此 cookie(当用户未登录时)。这些请求也会重定向到/error端点,该端点每次都会返回HttpServletResponse401状态,但这里不包含“Set-Cookie”标头。
用户使用授权标头登录后,响应将设置正确的 cookie 并在以下请求中使用。
问题是,有时设置的 cookie 会突然再次更改为无效 cookie,并且使用此新的无效 cookie 完成的后续请求会重定向到登录页面。
检查代码后,似乎发生了一个旧api/v1/notification请求(在登录请求之前),其中包含无效的 cookie(匿名请求,在登录之前存在)。
该请求被重定向到/error端点:这里再次HttpServletResponse出现401状态,并且包含一个 Set-Cookie 标头,该标头正在修改浏览器 cookie(替换好的 cookie)。
以下是问题的示意图,希望可以更容易理解。
我想阻止未经授权的请求设置会话 cookie。
如果先前的请求以 401 代码响应也没关系,但我不希望它更改当前设置的 cookie。
我尝试ErrorController通过返回 a来扩展ResponseEntity,其中包含输入中HttpServletResponse除“Set-Cookie”标头之外的所有标头。这是行不通的。
我还尝试修改我的配置以禁用匿名请求:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final String[] authorizedWithoutAuth = {
"/",
"/index.html",
"/static/**"
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers(authorizedWithoutAuth).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.and()
.logout().logoutUrl("/api/v1/logout").invalidateHttpSession(true)
.deleteCookies("mySessionCookie");
}
}
Run Code Online (Sandbox Code Playgroud)
但是会话cookie仍然是这样设置的,有401请求。
我还尝试使用@ControllerAdvice来处理异常,但这些异常是由 Spring Security 在 中抛出的AbstractSecurityInterceptor,如本响应中所述。
感谢大家抽出时间。抱歉帖子太长了:)
我开始深入研究 Spring Security 库,并注意到会话 cookie 是在HttpSessionRequestCache.saveRequest(...)方法中设置的:
public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
if (!this.requestMatcher.matches(request)) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.format("Did not save request since it did not match [%s]", this.requestMatcher));
}
} else {
DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, this.portResolver);
if (!this.createSessionAllowed && request.getSession(false) == null) {
this.logger.trace("Did not save request since there's no session and createSessionAllowed is false");
} else {
request.getSession().setAttribute(this.sessionAttrName, savedRequest);
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Saved request %s to session", savedRequest.getRedirectUrl()));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
创建对象时会出现“Set-Cookie”标头DefaultSavedRequest。我将其更改WebSecurityConfig为以下内容:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.requestCache().requestCache(getHttpSessionRequestCache()) // This is new
.and()
.authorizeRequests().antMatchers(authorizedWithoutAuth).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.and()
.logout().logoutUrl("/api/v1/logout").invalidateHttpSession(true)
.deleteCookies("mySessionCookie");
}
public HttpSessionRequestCache getHttpSessionRequestCache()
{
HttpSessionRequestCache httpSessionRequestCache = new HttpSessionRequestCache();
httpSessionRequestCache.setCreateSessionAllowed(false); // I modified this parameter
return httpSessionRequestCache;
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以了。使用授权标头登录时,cookie 设置正确,但所有具有无效会话 cookie 或过期会话 cookie 的请求都会返回响应,401而不会设置新的响应。
另外,读完这个答案后,我更好地理解了这createSessionAllowed是在做什么
| 归档时间: |
|
| 查看次数: |
1277 次 |
| 最近记录: |