我们在使用 Flex 4、BlazeDS 和 WebLogic 10.3.5 重新登录 Flex 应用程序中时遇到问题。
导致问题的用例如下所示:
- 在浏览器中启动应用程序。
- 重定向到带有j_security_check操作的登录表单页面。
- 登录并使用应用程序。
- 点击浏览器中的"返回"按钮。
- 再次进入登录表单页面。
- 再次登录。
- 在 BlazeDS 中获取异常并在 Flex/ActionScript 中捕获错误。
在 WLS 上登录时捕获的异常:
[BlazeDS]Unexpected error encountered in Message Broker servlet
flex.messaging.LocalizedException: The FlexSession is invalid.
at flex.messaging.FlexSession.checkValid(FlexSession.java:943)
at flex.messaging.FlexSession.getUserPrincipal(FlexSession.java:254)
at flex.messaging.HttpFlexSession.getUserPrincipal(HttpFlexSession.java:286)
at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:296)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:183)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3717)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
在 Flex/ActionScript 中捕获的错误:
faultCode: Client.Error.MessageSend
faultString: Send failed
faultDetail: Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 500: url: 'http://server:port/web-project/messagebroker/amf'
似乎是 BlazeDS 获得第二个会话,而第一个会话仍然有效且处于活动状态。
有谁知道,这究竟导致了这个问题以及如何优雅地解决这些问题?我有一些提示,但不知道它们是否足够合适:
- 在 Flex/ActionScript 中捕获故障,重定向到注销页面以使会话无效,然后重定向到登录页面并创建新会话。
- 通过JavaScript禁用浏览器中的"后退"按钮。
我将不胜感激任何建议,解释和建议。谢谢。
问题是会话固定。
发生什么:
- 您登录
- 您获得会话
- 您获得弹性会话(设置为会话属性)
- 您单击返回按钮
- 您登录(传入旧的 jsessionid)
春季会议固定保护策略:
- 检测 JSESSIONID 的会话是否有效
- 提取旧会话的属性
- 使会话无效(销毁它)
- 创建新会话
- 将旧会话的属性传输到新会话
当旧会话被销毁时,弹性会话将变为"无效"。
创建会话时会再次创建弹性会话,并且由于策略传递的引用相同,因此无效(浓重的俄罗斯口音)"我们有问题"
通过将策略bMigrateAttributes
设置为 false,可以轻松解决此问题:
<security:session-management session-authentication-strategy-ref="sas" />
<bean id="sas class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy" p:migrateSessionAttributes="false"/>
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/session-mgmt.html
希望这有帮助
我遇到了同样的问题,但我想保留所有会话属性,而不仅仅是 Spring 属性,所以我没有将 migrateSessionAttributes 设置为 false 以保留会话固定的非 spring 属性。
我最终覆盖了会话固定保护策略,因此我仍然可以从将迁移所有属性的会话固定中受益。
在onSessionChange方法中,我专门删除了"__flexSession"属性
package xxxxx;
import javax.servlet.http.HttpSession;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.stereotype.Component;
@Component
public class MySessionFixationProtectionStrategy extends SessionFixationProtectionStrategy {
private static String FLEX_SESSION_ATTRIBUTE = "__flexSession";
@Override
protected void onSessionChange(String originalSessionId, HttpSession newSession, Authentication authentication) {
// We remove the flex session attribute to avoid "The FlexSession is invalid." exception
newSession.removeAttribute(FLEX_SESSION_ATTRIBUTE);
super.onSessionChange(originalSessionId, newSession, authentication);
}
}