HttpSession session=request.getSession(true);
我在www.someurl.com的控制器中注意到,会话ID在步骤2和步骤4中有所不同。看起来Spring Security创建了一个新会话,该会话现在附加到公共页面请求。为什么会发生这种情况,我是否可以强制Spring Security使用现有会话?
答案 0 :(得分:9)
你的诊断错误了:
我在www.someurl.com的控制器中注意到,会话ID在步骤2和步骤4中有所不同。看起来Spring Security创建了一个新会话,该会话现在附加到公共页面请求。
正是因为所有页面都使用相同的会话,当您返回第一个选项卡并刷新时,您仍然以管理员身份登录。给定浏览器的所有选项卡和框架共享给定webapp的相同会话。这就是它的工作原理。服务器不知道并关心浏览器选项卡。它获取附加到给定浏览器发送的所有请求的会话cookie,并使用此cookie来获取相应的会话。这实际上是件好事。如果没有它,每次打开一个已经过身份验证的新选项卡时,都必须再次进行身份验证。而且你绝对不希望这样。
让我们解释一下你的场景中会发生什么:
会话固定攻击是潜在的风险,恶意攻击者可能通过访问站点创建会话,然后说服其他用户使用同一会话登录(通过向他们发送包含会话标识符的链接作为参数,例如)。 Spring Security通过在用户登录时创建新会话来自动防止这种情况。如果您不需要此保护,或者它与其他一些要求冲突,您可以使用session-fixation-protection属性控制行为,有三个选项
migrateSession - 创建新会话并将现有会话属性复制到新会话。这是默认设置。
none - 不做任何事情。原始会话将被保留。
newSession - 创建新的“干净”会话,而不复制现有的会话数据。
答案 1 :(得分:3)
您需要更改HttpSessionRequestCache
的行为,以便在不存在会话时不会创建会话。
您可以通过在XML配置中创建其实例来实现,如下所示:
<beans:bean id="httpSessionRequestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
<beans:property name="createSessionAllowed" value="false" />
</beans:bean>
然后,您需要在spring security config中配置http元素以使用您的bean实例:
<http auto-config="true" ....>
<request-cache ref="httpSessionRequestCache"/>
... rest of your config
</http>
如果您正在使用JSP,则还应该阻止JSP创建会话。为了做到这一点,您需要在每个JSP 之上添加page
指令(甚至是其他JSP包含的指令)。
<%@ page session="false" %>