Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
弹簧&x27;s SessionFixationProtectionStrategy终止JBoss/Weld下的CDI会话_Jboss_Spring Security_Cdi_Jboss Weld_Session Fixation - Fatal编程技术网

弹簧&x27;s SessionFixationProtectionStrategy终止JBoss/Weld下的CDI会话

弹簧&x27;s SessionFixationProtectionStrategy终止JBoss/Weld下的CDI会话,jboss,spring-security,cdi,jboss-weld,session-fixation,Jboss,Spring Security,Cdi,Jboss Weld,Session Fixation,我有一个标记为@ConversationScope的对象,在向导的许多步骤之间使用 这非常有效,只是当我的用户登录时,Spring的SessionFixationProtectionStrategy调用session.invalidate()方法以使用新id重新创建一个新会话。然后,它将失效会话的属性重新附加到新会话 问题是有一个WeldListener实例绑定到sessionDestroyed事件,它将杀死绑定到HttpSession对象的@ConversationScope实例 我已经禁用了

我有一个标记为@ConversationScope的对象,在向导的许多步骤之间使用

这非常有效,只是当我的用户登录时,Spring的SessionFixationProtectionStrategy调用session.invalidate()方法以使用新id重新创建一个新会话。然后,它将失效会话的属性重新附加到新会话

问题是有一个WeldListener实例绑定到sessionDestroyed事件,它将杀死绑定到HttpSession对象的@ConversationScope实例

我已经禁用了SessionFixationProtectionStrategy,现在使用的是NullAuthenticatedSessionStrategy,它什么也不做,但是我仍然希望保留会话固定策略来保护我的站点不受此影响


对如何解决这个问题有什么建议吗

通过在用户进行身份验证时设置自定义随机cookie,并在每次收到用户请求时进行检查,可以实现相同的效果

编写一个自定义的
AuthenticationSuccessStrategy
来设置cookie,例如:

public class MySessionAS extends SavedRequestAwareAuthenticationSuccessHandler {

    /**
     * Called after the user has successfully logged in.
     */
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) {
        // Generate random value
        String myAuthToken = ...
        request.getSession().setAttribute("myAuthToken", myAuthToken);
        Cookie myAuthCookie = new Cookie("myAppCookie", myAuthToken);
        myAuthCookie.setSecure(true); // You're using HTTPS, right?
        myAuthCookie.setMaxAge(-1); // It's a session cookie.
        response.addCookie(cookie);
        super.onAuthenticationSuccess(request, response, authentication);
    }
}
并将其插入您的
表单登录
配置中


然后您只需要检查值。一个很好的方法是在web中的自定义投票者
AccessDecisionManager
,或者如果这听起来太复杂,您可以使用自定义筛选器来检查用户是否经过身份验证(非空
SecurityContext
),以及是否经过身份验证,确保提交的cookie的值与会话中存储的值匹配。

以下是我使用的策略:

  • 从当前会话中分离焊接上下文(会话和对话)
  • 复制所有会话属性后,在使会话无效之前将其从会话中删除(由于某些原因,不这样做不起作用,可能是weld中的某个会话破坏侦听器)
  • 创建新会话,从上一个会话复制属性
  • 重新连接焊缝
  • 您需要复制SessionFixationProtectionStrategy类才能实现这一点,因为还没有合适的挂钩。这是身份验证

    public void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
            boolean hadSessionAlready = request.getSession(false) != null;
    
            if (!hadSessionAlready && !alwaysCreateSession) {
                // Session fixation isn't a problem if there's no session
    
                return;
            }
    
            // Create new session if necessary
            HttpSession session = request.getSession();
    
            if (hadSessionAlready && request.isRequestedSessionIdValid()) {
                // We need to migrate to a new session
                String originalSessionId = session.getId();
    
                if (logger.isDebugEnabled()) {
                    logger.debug("Invalidating session with Id '" + originalSessionId +"' " + (migrateSessionAttributes ?
                            "and" : "without") +  " migrating attributes.");
                }
    
                String id = weldAwareSessionFixationProtectionStrategyHelper.beforeInvalidateSession( request );
    
                Map<String, Object> attributesToMigrate = extractAttributes(session);
    
                for( String key : attributesToMigrate.keySet() ) {
                    session.removeAttribute( key );
                }
    
    
                session.invalidate();
                session = request.getSession(true); // we now have a new session
    
                if (logger.isDebugEnabled()) {
                    logger.debug("Started new session: " + session.getId());
                }
    
    
                if (originalSessionId.equals(session.getId())) {
                    logger.warn("Your servlet container did not change the session ID when a new session was     created. You will" +
                            " not be adequately protected against session-fixation attacks");
                }
    
                transferAttributes(attributesToMigrate, session);
    
                weldAwareSessionFixationProtectionStrategyHelper.afterCreateNewSession( request, id );
    
                onSessionChange(originalSessionId, session, authentication);
            }
        }
    

    您使用的是哪个spring安全版本?我使用的是spring安全3.1.0和JBoss 7
    @ApplicationScoped
    public class WeldAwareSessionFixationProtectionStrategyHelper {
    
        @Inject
        private HttpSessionContext httpSessionContext;
    
        @Inject
        private HttpConversationContext httpConversationContext;
    
        public String beforeInvalidateSession( HttpServletRequest httpServletRequest ) {
    
            String currentId = null;
    
            if( !httpConversationContext.getCurrentConversation().isTransient() ) {
                currentId = httpConversationContext.getCurrentConversation().getId();
            }
    
            httpConversationContext.deactivate();
            httpConversationContext.dissociate( httpServletRequest );
    
            httpSessionContext.deactivate();
            httpSessionContext.dissociate( httpServletRequest );
    
            return currentId;
        }
    
        public void afterCreateNewSession( HttpServletRequest httpServletRequest, String cid ) {
    
            httpSessionContext.associate( httpServletRequest );
            httpSessionContext.activate();
    
            httpConversationContext.associate( httpServletRequest );
    
            if( cid == null ) {
                httpConversationContext.activate();
            } else {
                httpConversationContext.activate( cid );            
            }
        }
    }