在同一场战争中防止弹簧会话覆盖

时间:2016-09-12 10:28:29

标签: spring session spring-security token spring-security-oauth2

假设我有一个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>

2 个答案:

答案 0 :(得分:2)

如果所有前端都在同一场战争中,那就是打算发生的事情。

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

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

答案 1 :(得分:0)

您的浏览器必须将所有请求的会话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重写
  • 禁止再次登录