我正在使用Spring Security构建一个Web应用程序,该应用程序将存在于Amazon EC2上并使用Amazon的Elastic Load Balancers . 不幸的是,ELB不支持粘性会话,因此我需要确保我的应用程序在没有会话的情况下正常工作 .
到目前为止,我已经设置了RememberMeServices来通过cookie分配一个令牌,这很好用,但我希望cookie随浏览器会话一起过期(例如当浏览器关闭时) .
我不得不想象我不是第一个想要在没有会话的情况下使用Spring Security的人......有什么建议吗?
7 回答
在带有Java Config的Spring Security 3中,您可以使用HttpSecurity.sessionManagement():
我们今天处理了相同的问题(向SecurityContextPersistenceFilter注入自定义SecurityContextRepository)4-5小时 . 最后,我们弄明白了 . 首先,在Spring Security引用的8.3节中 . doc,有一个SecurityContextPersistenceFilter bean定义
在此定义之后,有这样的解释:“或者,您可以提供SecurityContextRepository接口的null实现,这将阻止安全上下文的存储,即使在请求期间已经创建了会话 . ”
我们需要将自定义SecurityContextRepository注入SecurityContextPersistenceFilter . 因此,我们只需使用自定义impl更改上面的bean定义,并将其置于安全上下文中 .
当我们运行应用程序时,我们跟踪日志并看到SecurityContextPersistenceFilter没有使用我们的自定义impl,它使用的是HttpSessionSecurityContextRepository .
在我们尝试了一些其他的事情之后,我们发现我们必须使用“http”命名空间的“security-context-repository-ref”属性给我们的自定义SecurityContextRepository impl . 如果您使用“http”命名空间并想要注入自己的SecurityContextRepository impl,请尝试“security-context-repository-ref”属性 .
使用“http”命名空间时,将忽略单独的SecurityContextPersistenceFilter定义 . 正如我上面复制的那样,参考文档 . 没有说明 .
如果我误解了这些事情,请纠正我 .
在Spring Securitiy 3.0中,它似乎更容易 . 如果您正在使用命名空间配置,则可以执行以下操作:
或者您可以将SecurityContextRepository配置为null,并且不会以任何方式保存as well .
看看
SecurityContextPersistenceFilter
课程 . 它定义了如何填充SecurityContextHolder
. 默认情况下,它使用HttpSessionSecurityContextRepository
在http会话中存储安全上下文 .我已经很容易地使用自定义
SecurityContextRepository
实现了这个机制 .见下面的
securityContext.xml
:实际上,在Spring Security问题管理中没有't mean being completely stateless. There' s an issue .
快速说明一下:它是“创建会话”而不是“创建会话”
create-session
控制创建HTTP会话的渴望程度 .
如果未设置,则默认为“ifRequired” . 其他选项是“永远”和“从不” .
此属性的设置会影响HttpSessionContextIntegrationFilter的allowSessionCreation和forceEagerSessionCreation属性 . 除非将此属性设置为“never”,否则allowSessionCreation将始终为true . forceEagerSessionCreation为“false”,除非它设置为“always” .
因此,默认配置允许创建会话,但不强制它 . 例外情况是,如果启用了并发会话控制,则forceEagerSessionCreation将设置为true,而不管此处的设置是什么 . 使用“never”会在HttpSessionContextIntegrationFilter初始化期间导致异常 .
有关会话使用的具体细节,HttpSessionSecurityContextRepository javadoc中有一些很好的文档 .
在使用了这个答案中发布的众多解决方案之后,为了在使用
<http>
命名空间配置时尝试获得一些工作,我终于找到了一种实际适用于我的用例的方法 . 我没有't actually require that Spring Security doesn' t启动一个会话(因为我在应用程序的其他部分使用会话),只是它在会话中根本没有"remember"身份验证(应该重新检查每个请求) .首先,我不清楚你是否应该将securityContextRepository设置为
null
或者设置为no-op实现 . 前者不起作用,因为NullPointerException
在SecurityContextPersistenceFilter.doFilter()
内被抛出 . 至于无操作实现,我尝试以我能想象的最简单的方式实现:这在我的应用程序中不起作用,因为有一些奇怪的
ClassCastException
与response_
类型有关 .即使假设我确实设法找到一个有效的实现(通过简单地不在会话中存储上下文),仍然存在如何将其注入由
<http>
配置构建的过滤器的问题 . 根据docs,您不能简单地在SECURITY_CONTEXT_FILTER
位置更换过滤器 . 我发现挂钩在封面下创建的SecurityContextPersistenceFilter
的唯一方法是编写一个丑陋的ApplicationContextAware
bean:无论如何,对于实际工作的解决方案,尽管非常hackish . 只需使用
Filter
删除HttpSessionSecurityContextRepository
在执行其操作时查找的会话条目:然后在配置中: