【发布时间】:2021-04-10 15:15:31
【问题描述】:
我有一个 Spring Boot 应用程序,步骤如下:
- 用户登录到应用程序
- 用户按下按钮即可用卡支付一定金额
- 用户正在重定向到卡处理/支付站点,他必须在其中填写卡号、日期和其他内容
- 成功后,卡片网站将重定向到应用程序的反向引用,位于 /card-response
- spring 控制器映射在 /card-response 过程中,进一步处理支付结果并结束支付循环
问题:
在 Mozilla Firefox 中一切正常
在 Chrome 浏览器中第一次似乎没问题(所有步骤 1-5),但经过多次(可以是第二次、第三次或更多随机方式)应用程序显示登录页面(在第 4 步返回时application /card-response) 作为用户未经身份验证。
如果我在步骤 4 之前和之后(在 Application->Cookies 处)检查浏览器中的会话 cookie (JSESSIONID) 并且相同,未更改。 此外,在应用程序显示登录页面后,如果我直接在浏览器中输入 URL /card-response,我可以在没有登录页面的情况下访问应用程序,因此应用程序认为我已通过身份验证
来自spring应用日志:
DEBUG org.springframework.security.web.access.ExceptionTranslationFilter@4f5a3111, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3fdb1ce4]] (1/1)
DEBUG org.springframework.security.web.FilterChainProxy - Securing POST /card-response
TRACE org.springframework.security.web.FilterChainProxy - Invoking WebAsyncManagerIntegrationFilter (1/13)
TRACE org.springframework.security.web.FilterChainProxy - Invoking SecurityContextPersistenceFilter (2/13)
TRACE org.springframework.security.web.context.HttpSessionSecurityContextRepository - **No HttpSession currently exists**
TRACE org.springframework.security.web.context.HttpSessionSecurityContextRepository - Created SecurityContextImpl [Null authentication]
DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - Set SecurityContextHolder to empty SecurityContext
在 WebSecurityConfig 我有
http
.authorizeRequests()
.antMatchers("/resources/free/**").permitAll()
.antMatchers("/rest-mock/**").permitAll()
.antMatchers("/reset-password-init").permitAll()
.antMatchers("/reset-password/**").permitAll()
.antMatchers("/remote-login/**").permitAll()
.antMatchers("/check-certificate/**").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").successHandler(successHandler).permitAll()
.and().exceptionHandling().accessDeniedPage("/logout")
.and().logout().invalidateHttpSession(true).clearAuthentication(true).deleteCookies("JSESSIONID").permitAll()
.and().csrf()
.ignoringAntMatchers("/card-response/**","/rest-mock/**");
如果步骤 4 没问题(始终使用 Firefox 访问,有时使用 Chrome 访问),则 Spring 应用程序日志为:
DEBUG org.springframework.security.web.FilterChainProxy - Securing GET /card-response
TRACE org.springframework.security.web.FilterChainProxy - Invoking WebAsyncManagerIntegrationFilter (1/13)
TRACE org.springframework.security.web.FilterChainProxy - Invoking SecurityContextPersistenceFilter (2/13)
TRACE org.springframework.security.web.context.HttpSessionSecurityContextRepository - Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=User [id=28327, user_name=xxxxxxxxxx, first_name=xxxxxxxxxx, last_name=xxxxxxxxxx, email=xxxxx@domain.ro], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=D24B7748BA6C2C59B1C4FAB3D16C6B19], Granted Authorities=[Role [id=3, name=Lawyer]]]] from SPRING_SECURITY_CONTEXT
DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - Set SecurityContextHolder to SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=User [id=28327, user_name=xxxxxxxxxx, first_name=xxxxxxxxxx, last_name=xxxxxxxxxx, email=xxxxx@domain.ro], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [SessionId=D24B7748BA6C2C59B1C4FAB3D16C6B19], Granted Authorities=[Role [id=3, name=Lawyer]]]]
TRACE org.springframework.security.web.FilterChainProxy - Invoking HeaderWriterFilter (3/13)
所以这个上下文中的会话不为空,一切正常
问题是为什么 spring security 获取空会话并记录“当前不存在 HttpSession”,但在 Chrome 浏览器中,会话 cookie 在开始时没有改变,在第 1 步。
对于第 4 步的成功,请求标头包含 cookie:
POST /caav_interface/card-response HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Content-Length: 281
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=7B0E48E550B98EAE6CBF2D7E2AB76B59
对于不成功的请求不包含它:
POST /caav_interface/card-response HTTP/1.1
Host: localhost:8081
Connection: keep-alive
Content-Length: 281
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
所以 Chrome 似乎并不总是在标头中传递 cookie。
【问题讨论】:
-
Spring Security 不管理会话,因此它并不真正掌握在 Spring Security 手中。您收到的错误消息意味着当 Spring Security 向 Servlet API 询问会话时,没有返回任何内容。如果您也在使用该模块,您的网络流量可能是寻找问题的更好地方,或者可能是您的 Spring Session 配置。
-
嗨,你能指导我调试这个需要什么信息吗?在浏览器会话中,cookie 存在且未更改,那么为什么会话为空?为什么在 Firefox 中一切正常?
-
不同的事情可以使应用服务器找不到会话。这两个应用程序是否在同一个域(例如 localhost)上,它们是否都有 JSESSIONID?您的应用程序是否在代理后面?您是否在 JSESSIONID cookie 上使用 SameSite 属性?如果您可以分享成功和失败握手的网络流量样本,或许会有所帮助。
-
不,第一个应用程序在本地主机上,卡应用程序是远程的
-
我用一些网络流量编辑了我的问题
标签: spring spring-boot spring-security