0

@ConversationScoped としてマークされ、ウィザードの多くのステップ間で使用されるオブジェクトがあります。

これは、私のユーザーがログインしているときに、Spring の SessionFixationProtectionStrategy が session.invalidate() メソッドを呼び出して、新しい ID で新しいセッションを再作成することを除いて、完全に機能します。次に、無効化されたセッションの属性を新しいセッションに再アタッチします。

問題は、sessionDestroyed イベントにバインドされ、HttpSession オブジェクトにバインドされた @ConversationScoped インスタンスを強制終了する WeldListener インスタンスがあることです。

私は SessionFixationProtectionStrategy を無効にし、現在何もしない NullAuthenticatedSessionStrategy を使用していますが、これからも自分のサイトを保護するためにセッション固定戦略を維持したいと考えています。

これを回避する方法について何か提案はありますか?

4

2 に答える 2

0

ユーザーの認証時にカスタム ランダム 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);
    }
}

それを構成にプラグインしform-loginます。

次に、値を確認するだけです。これを行うのに適した場所は、 Web のカスタム ボーターです。AccessDecisionManagerまたは、それが複雑すぎると思われる場合は、カスタム フィルターを使用して、ユーザーが認証されているかどうか (非空SecurityContext) を確認し、認証されている場合は値を確認します。送信された Cookie の値は、セッションに保存されている値と一致します。

于 2012-08-23T17:38:56.047 に答える
0

これが私が使用している戦略です:

  1. 現在のセッションから溶接コンテキスト (セッションと会話) を切り離します。
  2. すべてのセッション属性をコピーした後、セッションを無効にする前にそれらをセッションから削除します (何らかの理由でこれを行わないと機能しません。おそらく、溶接のどこかにあるセッション破壊リスナーです)。
  3. 新しいセッションを作成し、前のセッションから属性をコピーします
  4. 溶接コンテキストを再接続します。

適切なフックが既に配置されていないため、これを実装できるように SessionFixationProtectionStrategy クラスをコピーする必要があります。これが onAuthenticate です。

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);
        }
    }

...そして、これが WeldAwareSessionFixationProtectionStrategyHelper です

@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 );            
        }
    }
}
于 2012-12-08T13:39:34.887 に答える