首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HttpSessionSecurityContextRepository -没有HttpSession,只有Chrome

HttpSessionSecurityContextRepository -没有HttpSession,只有Chrome
EN

Stack Overflow用户
提问于 2021-01-04 20:19:53
回答 1查看 583关注 0票数 0

我有一个spring引导应用程序,其步骤如下:

用户登录到application

  • users,按一个按钮支付一定金额的卡

  • 用户重定向到卡处理/付费站点,在那里他必须填写卡号、日期和其他东西

  • 在成功后,卡站点重定向到一个回引用到应用程序,在/card-response

  • spring控制器上映射到/卡响应处理,进一步完成支付结果并结束支付循环

问题:

在Mozilla Firefox中一切都很好

在Chrome浏览器中,第一次似乎没有问题(所有步骤1-5),但经过多次(可以是第二次、第三次或更多次随机方式)之后,应用程序将显示登录页面(返回到应用程序/卡片响应时的步骤4),因为用户是未经身份验证的。

如果我在第4步之前和之后(在Application->Cookies)之前和之后在浏览器中检查会话cookie (JSESSIONID),并且是相同的,不变的。此外,在应用程序显示登录页后,如果我将URL /card-response直接放在浏览器中,则无需登录页面就可以访问应用程序,因此应用程序正在考虑我的身份验证。

在spring应用程序日志中:

代码语言:javascript
复制
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我有

代码语言:javascript
复制
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 access,并不时使用Chrome access),那么spring应用程序日志是:

代码语言:javascript
复制
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安全性获得空会话并记录“当前不存在HttpSession”,但是在Chrome会话cookie中,在第一步开始时没有改变。

对于步骤4的成功,请求头包含cookie:

代码语言:javascript
复制
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

对于不成功的请求,请求不包含它:

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

发布于 2021-01-08 13:55:50

解决办法:

Chrome考虑不带SameSite属性的JSESSIONID禁止在不同站点之间传递它。

因此,cookie必须有属性"SameSite=None;Secure“才能在站点之间传递它。

有时候在Chrome中工作的原因是Chrome在最初的1到2分钟内在站点之间传递它。

属性安全是必要的,因为Chrome考虑在没有SSL/TLS上下文的站点之间传递cookie是不安全的。

考虑到对于本地测试/开发,您必须省略这些属性,或者在Firefox浏览器上进行测试。

在java中实现:从onAuthenticationSuccess重写SavedRequestAwareAuthenticationSuccessHandler方法

代码语言:javascript
复制
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
        boolean firstHeader = true;
        // there can be multiple Set-Cookie attributes
        for (String header : headers) {
            if (firstHeader) {
                response.setHeader(HttpHeaders.SET_COOKIE,
                        String.format("%s; %s", header, "SameSite=None; Secure"));
                firstHeader = false;
                continue;
            }
            response.addHeader(HttpHeaders.SET_COOKIE,
                    String.format("%s; %s", header, "SameSite=None; Secure"));
        }

谢谢你为我指明了正确的方向!

希望能帮上忙,我花了很多时间在这上面

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65569279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档