2016-05-25 58 views
6

このコードをspring-security.xmlに追加して、セッションタイムアウトチェックと同時実行性チェックを有効にしました。Spring Securityのセッション管理(タイムアウト/並行性チェック)からいくつかのページを除外する方法は?

<sec:http> 
    <sec:form-login login-page="/login" login-processing-url="/authentication" 
        default-target-url="/home" always-use-default-target="true" 
        authentication-failure-url="/login?error=true" 
        username-parameter="userid" password-parameter="password"/> 
    <sec:logout logout-url="/logout" logout-success-url="/login" delete-cookies="JSESSIONID" invalidate-session="true" /> 

    <!-- User login (URL not View Name) --> 
    <sec:intercept-url pattern="/login" access="permitAll" /> 

    <!-- User change password --> 
    <sec:intercept-url pattern="/change_password" access="permitAll" /> 


    <sec:session-management invalid-session-url="/session_timeout"> 
     <sec:concurrency-control max-sessions="1" error-if-maximum-exceeded="false" expired-url="/session_conflict"/> 
    </sec:session-management> 

    <sec:headers> 
     <sec:frame-options policy="SAMEORIGIN" /> 
    </sec:headers> 
</sec:http> 

しかし、問題は

  1. 、である私は、セッションのチェック(タイムアウトと同時実行)からloginchange_passwordのようないくつかのページを除外する必要があります。

  2. ログオンユーザーまたはログアウトユーザーの両方にアクセスできるページがある場合は、しかし、私は、ユーザーがログインしたときにのみセッションタイムアウトと同時実行チェックを行う必要があります。

どのように私はこれを実装する必要がありますか?

ありがとうございました。

答えて

4

アップデート:私のSpring Securityログインページの1つで私のオリジナルのsession="false"答えをテストしたが、うまくいかなかった。より良い解決策については、以下を参照してください。


オリジナルの答え

が開始されてからセッションを防ぐ必要があるJSPファイルの先頭に<% @ページセッション=「false」に%>を追加するが、これは春のセキュリティとは無関係です。

いくつかの非常に最小限のOracleのドキュメントは、その下のURLにありますは言う:

JSPのデフォルトのセッション要求

は、一般的に言えば、サーブレットは デフォルトでHTTPセッションを要求しません。ただし、JSPページ実装クラスはデフォルトでHTTP セッションを要求します。次のようにあなたは、JSPページディレクティブでfalseにセッション パラメータを設定することでこれをオーバーライドすることができます。

<%の@ページ...セッション= "false" に%

https://docs.oracle.com/cd/A87860_01/doc/java.817/a83726/basics3.htm#1007356


回答が更新:この問題は、CSRFが有効になっているSpring Securityに関連している可能性があります。バージョン4.0ではデフォルトで有効になっていますが、無効にしたいものではありません。以前のバージョンでは、手動で行う必要があったかもしれません。

CRSFトークンはセッションを必要とするため、ログインプロセスだけでCSRFテストを除外するソリューションが必要です。

"Relaxing CSRF"の説明は、「Spring Security Reference」にあります。彼らは特にSockJSについて言及していますが、原則は普遍的です。

http.csrf().ignoringAntMatchers("/login") 

受け入れanswer by P.Peter for the SO question "CSRF token expires during login"はもう少し努力が必要同様のソリューションを持っている:彼らはJavaConfigについては、以下の行のようなものを示唆しています。

あなたは春のRequestMatcherクラスを実装するクラスを追加し、方法)(それの試合を上書きする必要があります。

class CsrfSecurityRequestMatcher implements RequestMatcher { 
    @Override 
    public boolean matches(HttpServletRequest request) { 
     return !request.getServletPath().equals("/login"); 
    } 
} 

あなたは、より複雑なマッチングロジックが必要な場合は、カスタムRequestMatcherクラスでパターンとRegexRequestMatcherフィールドを追加することができますmatches()メソッドでそれらを使用します。

次に、Springセキュリティコンフィグレーションで新しいクラスへの参照を追加する必要があります。私は、ログインページにCSRFのテストを無効にするがあるかもしれないものをセキュリティ波及効果が不明だ

http.csrf().requireCsrfProtectionMatcher(new CsrfSecurityRequestMatcher()); 

:それはこのようなものになるだろうJavaConfigで

<http> 
    <csrf request-matcher-ref="csrfSecurityRequestMatcher"/> 
</http> 

:XMLではこのようなものになるだろうだからあなたはそれを調べたいかもしれません。

ログインページのCSRFを無効にすることが許容できないと判断した場合は、ログインページが期限切れになるのを防ぐAJAXキープアライブソリューションを使用できますが、これはちょっとした趣味です。

3

セッションは、スプリング、セキュリティなどに関係なく作成されます。セッションの後ろのメカニズムは完全に自動であり、変更や操作は必要ありません。 Springの詳細を掘り下げる代わりに、プレーンなjavax.servlet APIを使用して必要なものを達成することができます。

あなたがする必要があるのは、セッションバインドされたカスタムオブジェクトの助けを借りて、匿名セッションと認証されたユーザーセッションを区別することです。

セッションはオブジェクトを保持でき、サーバーは特定のセッション(通常はセッションcookie jsessionidを介して)にバインドされたオブジェクトを保持します。このようなオブジェクトの例は、次のコードです:ユーザーが正常に検証された後、あなたの許可および認証コードで

import java.util.logging.Logger; 
import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 

public class SessionListener implements HttpSessionListener { 

    public static final Logger log = Logger.getLogger(SessionListener.class.getCanonicalName()); 

    /** 
    * Method is called after new client connects 
    * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) 
    */ 
    @Override 
    public void sessionCreated(HttpSessionEvent arg0) { 
     log.info("SESSION CREATED with id " + arg0.getSession().getId()); 
     final SessionUsr authenticatedUser = new SessionUsr(false, "anonymous"); 
     arg0.getSession().setAttribute("_USR", authenticatedUser); 
    } 

    /** 
    * Invalidation or timeout definined in web.xml (session-timeout). 
    * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
    */ 
    @Override 
    public void sessionDestroyed(HttpSessionEvent arg0) { 
     log.info("SESSION DESTROYED, INVALIDATED " + arg0.getSession().getId()); 
    } 

} 

イベントを追跡するために

public class SessionUsr implements java.io.Serializable { 
    private static final long serialVersionUID = 6034793247940424913L; 

    // do not make this fields nonfinal. This object is in session as serialized stream and 
    // setting the fields does not refresh the object in session. You must replace it 

    protected final boolean isAnonymous; 
    protected final String userName; 

    public SessionUsr(boolean isAnonymous, String userName) { 
     super(); 
     this.isAnonymous = isAnonymous; 
     this.userName = userName; 
    } 
    public boolean isAnonymous() { 
     return this.isAnonymous; 
    } 
    public String getUserName() { 
     return this.userName; 
    } 

    @Override 
    public String toString() { 
     return "SessionUsr [isAnonymous=" + this.isAnonymous + ", userName=" + this.userName + "]"; 
    } 
    @Override 
    public int hashCode() { 
     int result = 17; 
     result = 31 * result + (null == getUserName() ? 0 : getUserName().hashCode()); 
     result = 31 * result + (!isAnonymous() ? 0 : 1); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (!(obj instanceof SessionUsr)) { 
      return false; 
     } 

     final SessionUsr comparation= (SessionUsr) obj; 
     if (comparation.getUserName().equals(this.userName)) 
      return true; 

     return false; 
    } 

} 

セッションリスナーは、あなたがコード

とのセッション属性を置き換えます
final SessionUsr authorizated = new SessionUsr("John Kennedy", true); 
getSession().setAttribute("_USR", authorizated); 

そして、あなたがどこでも、このユーザーを取得できます。

final SessionUsr authenticatedUser = (SessionUsr) getSession().getAttribute("_USR"); 
関連する問題