在同一场战争中防止春季会话覆盖

Posted

技术标签:

【中文标题】在同一场战争中防止春季会话覆盖【英文标题】:Prevent spring session override in the same war 【发布时间】:2017-01-19 18:29:24 【问题描述】:

假设我有一个 WAR,它在 JSP 中有一个前端,并包含一个带有 REST API 的 JAR。

我有一个spring-security.xml,其中配置了多个 authenticationProviders。

我面临的问题如下:

用户(user1)通过基本认证(localhost/app1)登录到JSP前端 在同一浏览器上,不同的用户 (user2) 使用 oauth 令牌 (localhost/app2) 登录到不同的前端 只要将此令牌用于 REST 调用 (localhost/rest),来自 JSP 前端 (app1) 的用户 (user1) 就会被 user2 覆盖。

对于 REST API,create-session="never" 已启用。但是无论如何,来自 JSP 会话的用户都会被覆盖。

我正在使用 Spring 3.2.15 和 Spring Security 3.2.9

spring-security.xml的相关部分:

<!-- The configuration for the rest-api -->
<security:http pattern="/rest/**" create-session="never" use-expressions="true"
               entry-point-ref="authenticationEntryPoint">
    <security:anonymous enabled="false" />
    <security:intercept-url pattern="/rest/**" access="permitAll" method="OPTIONS" />
    <security:intercept-url pattern="/rest/**" access="isAuthenticated()" />
    <security:custom-filter ref="CORSFilter" position="FIRST" />
    <security:custom-filter ref="um-rest-resource-server" before="PRE_AUTH_FILTER" />
</security:http>

<!-- Other configration for the other endpoints (not under /rest/) ... -->

<oauth2:resource-server id="um-rest-resource-server" resource-id="um-rest-resource-server" token-services-ref="tokenVerifier" />

<bean id="tokenVerifier" class="be.healthconnect.iam.oauth2.verifier.TokenVerifier"></bean>

【问题讨论】:

【参考方案1】:

您的浏览器必须将所有请求的会话 cookie 发送到您的服务器。您的第二次调用(到 localhost/app2)包含会话 cookie,Spring Security 使用此会话(并更改您的用户)。

有一些解决方案,但如果您根本不需要会话,您可以通过设置create-session="stateless" 告诉 Spring Security 忽略请求中的会话 cookie,参见Spring Security Reference:

create-session 控制 Spring Security 类创建 HTTP 会话的急切程度。选项包括:

always - 如果会话不存在,Spring Security 将主动创建会话。 ifRequired - Spring Security 只有在需要时才会创建会话(默认值)。 never - Spring Security 永远不会创建会话,但如果应用程序创建了会话,则会使用它。 stateless - Spring Security 不会创建会话并忽略会话以获取 Spring Authentication

如果您需要会话,其他解决方案是:

单独的浏览器会话 分离 WAR 文件 会话 ID 的 URL 重写 不允许再次登录

【讨论】:

【参考方案2】:

如果所有前端都在同一场战争中,这就是预期发生的事情。

但是有一种方法可以让您有机会。如果您的 REST app2 实际上是完全无状态的,请尝试以这种方式将创建会话策略设置为无状态:create-session="stateless"

将会话创建策略设置为无状态时,SecurityContextHolder 甚至不会被检查以查找有效会话,也不会调用它来保存成功的身份验证。

【讨论】:

以上是关于在同一场战争中防止春季会话覆盖的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Django 覆盖 sessionid cookie?

防止浏览器选项卡之间的会话共享

生存战争怎么防止迷路

防止使用相同的登录凭据进行多次登录

¿如何在同一只耳朵的不同战争之间分享安全性和过滤器?

如何防止 Laravel 中的会话/cookie 刷新?