首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在我的Spring项目中添加Session会中断iframe中的身份验证

在我的Spring项目中添加Session会中断iframe中的身份验证
EN

Stack Overflow用户
提问于 2020-06-24 20:32:44
回答 1查看 430关注 0票数 0

我目前正在构建Spring应用程序(2.3.1,但使用Security保护的版本2.1.7和2.1.5也注意到了以下问题)。我主要使用默认设置(例如嵌入式Tomcat、嵌入式H2数据库、Spring )。我使用以下代码对允许的POST映射执行一些自定义身份验证:

代码语言:javascript
复制
UsernamePasswordAuthenticationToken authentication = ...;
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);

这个很好用。由于我想在学生考试中使用它,所以我希望持久化认证会话,所以如果服务器软件因某种原因崩溃或停机,当服务器再次出现时,没有人需要重新验证。

为此,我使用了Spring会话JDBC。我将以下依赖项添加到我的pom.xml

代码语言:javascript
复制
<dependency>
   <groupId>org.springframework.session</groupId>
   <artifactId>spring-session-jdbc</artifactId>
</dependency>

和我的application.properties的下面一行

代码语言:javascript
复制
spring.session.store-type=jdbc

当我在本地测试时,这一切都很好。我看到会话出现在我的数据库中,一切都很好。然而,在实践中,应用程序是从iframe启动的:学习管理系统执行LTI启动,这是一个POST请求,响应在iframe中结束。当我尝试进行测试部署时,我收到了一个403错误,请求没有经过身份验证。在经历了令人沮丧的一天调试之后,我终于能够将这个问题归结为这样一个事实:将spring-session-jdbc添加到我的项目中会导致web应用程序在iframe的每个请求上发送一个新的会话ID cookie。如果我在没有iframe的情况下重复相同的请求,那么相同的应用程序可以正常工作。如果我移除spring-session-jdbc依赖项,应用程序在iframe中也可以正常工作。

如果在iframe中执行身份验证,在Security调试日志中可以看到以下内容(exec-1是成功身份验证发生的地方,exec-2是iframe在被exec-1请求重定向后执行的请求):

代码语言:javascript
复制
2020-06-24 22:14:02.015 DEBUG 7474 --- [nio-8031-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@671fa7ec
2020-06-24 22:14:02.015 DEBUG 7474 --- [nio-8031-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-06-24 22:14:02.063 DEBUG 7474 --- [nio-8031-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-06-24 22:14:02.113 DEBUG 7474 --- [nio-8031-exec-2] o.s.security.web.FilterChainProxy        : /launch/development at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-06-24 22:14:02.113 DEBUG 7474 --- [nio-8031-exec-2] o.s.security.web.FilterChainProxy        : /launch/development at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-06-24 22:14:02.114 DEBUG 7474 --- [nio-8031-exec-2] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2020-06-24 22:14:02.114 DEBUG 7474 --- [nio-8031-exec-2] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.

当我在常规浏览器窗口中使用相同运行的应用程序执行相同请求时,Security调试日志显示如下:

代码语言:javascript
复制
2020-06-24 22:18:10.518 DEBUG 7474 --- [nio-8031-exec-5] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@671fa7ec
2020-06-24 22:18:10.518 DEBUG 7474 --- [nio-8031-exec-5] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e1239cdc: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e1239cdc: Principal: testuserid; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_INSTRUCTOR' stored to HttpSession: 'org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper@66670854
2020-06-24 22:18:10.536 DEBUG 7474 --- [nio-8031-exec-5] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2020-06-24 22:18:10.536 DEBUG 7474 --- [nio-8031-exec-5] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-06-24 22:18:10.590 DEBUG 7474 --- [nio-8031-exec-6] o.s.security.web.FilterChainProxy        : /home at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-06-24 22:18:10.591 DEBUG 7474 --- [nio-8031-exec-6] o.s.security.web.FilterChainProxy        : /home at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-06-24 22:18:10.592 DEBUG 7474 --- [nio-8031-exec-6] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@82a4fa0f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@82a4fa0f: Principal: testuserid; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_INSTRUCTOR'

对我来说,这似乎很奇怪:如果这纯粹是一个浏览器问题,那么我是否使用spring-session-jdbc并不重要。如果spring-session-jdbc如何存储我的身份验证存在问题,那么它是否发生在iframe中也不重要。这里有什么东西我遗漏了吗?我被虫子绊倒了吗?

我可以尝试一种解决方法,在iframe中使用一些javascript,让POST出现在一个空白选项卡中,但感觉很难看。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-25 09:07:04

总的来说,我建议你不要在iframe中使用你的应用程序。

这会带来安全风险,您可以在this answer中更多地了解这些风险。

现在来解释一下你所看到的行为。

Security使用Session cookie来存储用户的会话。

cookie与域相关联,因此,例如,如果存在与域stackoverflow.com相关联的cookie,那么该cookie将包含在对stackoverlow.com的任何请求中。

为了控制这种行为,cookie还具有一个名为SameSite的属性。

SameSite attribute可以有3个值,NoneLaxStrict

当值为None时,它的行为如上文所述(包括在所有请求中)。

当值为Lax时,cookie将只包含在顶级导航GET请求中。

当包含Spring会话依赖项时,默认情况下将Session cookie SameSite属性设置为Lax

因为在iframe中呈现应用程序不是顶级导航,所以Session cookie不包含在对iframe的请求中,并且应用程序无法知道用户已被登录。

您可以使用Session显式地将SameSite属性设置为None

同样,我要提醒您不要这样做,因为它会使您的应用程序容易受到CSRF和点击劫持攻击的攻击。

如果在考虑了安全性影响之后,您认为有必要将SameSite属性设置为None,则可以通过在依赖项中包含Spring会话并创建custom CookieSerializer来做到这一点。

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

https://stackoverflow.com/questions/62563620

复制
相关文章

相似问题

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