復旧remember-me cookieの後に期限切れになると、ユーザーセッションが正しく動作しません。セッションが終了した後にremember-meトークンによってApacheプロキシが正しくセッションを復旧しない
私はSpring Securityのremember-meオプションを有効にしていると、私は異常なエラーがあります。セッションが期限切れになると、残りのWebページはナビゲートできますが、ログアウトやその他のPOSTメソッドではサーバーにエラーが発生します。私のコントローラはPOSTの代わりにGETメソッドを受け取るので、動作しません。なぜか分からない。
まず、私はProxyPassの設定で、プロキシとして機能するApache httpdサービスを持っています。私はアプリの名前を示すことなく、自分のドメインにwww.example.comにアクセスしたいので、私は
(他人の言葉に、私はいけないwww.example.com/appNameを示す) ROOT.warとしての私の.warを展開しました私はこのケースについてのドキュメントをたくさん読んでいる、とvirtalホストの私の構成は次の行を持っている:春Scurityディレクティブの
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass/http://example.com:9080/
ProxyPassReverse/http://example.com:9080/
<Location />
Order allow,deny
Allow from all
</Location>
#FIX For Spring Security
RewriteEngine on
RewriteRule ^/(.*)$ http://example.com:9080/$1 [P,L]
修正は通常の認証フォームを使用した後、POSTメソッドのためにneccessaryです。
問題
JSSESIONIDクッキーの有効期限が切れる前に、私は正しくアプリケーションを使用することができます。私はログアウトすることができ、私はなど、他の方法でのポストを使用することができます...ここで問題なし。しかし、セッションが終了すると、何かがブローされます。私はWebページを通過して情報にアクセスすることはできません。認証のためにログインページにリダイレクトすることはできません(私はRemember-Me Cockieが機能することを理解しています)。しかしPOSTメソッドを使用すると、リクエストはGETメソッドを呼び出すためです。
私は同じ環境にアプリをテストしましたが、security-context.xmlでremember-me設定を無効にし、ROOT.warをデプロイして、セッションの有効期限が切れるとアプリをテストしました。ログインページが正しく表示されます。
ローカルのTomcat(Apacheのプロキシなし)では、私のwebappは両方の設定で正しく動作します:remember-meとremember-meなし。
セキュリティのcontext.xml
<bean id="csrfSecurityRequestMatcher" class="com.XXX.YYY.config.CsrfSecurityRequestMatcher"></bean>
<security:form-login
authentication-success-handler-ref="customAuthenticationSuccessHandler"
authentication-failure-url="/login?error"
login-page="/login"
password-parameter="lgPassword"
username-parameter="lgUsername" />
<security:logout
success-handler-ref="customLogoutSuccessHandler"
logout-url="/logout"
invalidate-session="true" />
<security:csrf
request-matcher-ref="csrfSecurityRequestMatcher"
disabled="false" />
<security:remember-me
user-service-ref="customUserDetailsService"
token-repository-ref="customPersistentTokenRepository"
remember-me-parameter="lgRememberMe"
remember-me-cookie="TRMMBRM"
token-validity-seconds="7776000" />
<security:session-management>
<security:concurrency-control
max-sessions="1"
expired-url="/login" />
</security:session-management>
web.xmlの(私の意見ではこのような場合のために、より重要な設定...)
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
<filter>
<display-name>springSecurityFilterChain</display-name>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Session Configuration-->
<session-config>
<session-timeout>1</session-timeout> <!-- (in minutes (1 min for test) -->
</session-config>
- JVMバージョン:1.8.0_151-b12
- Spring MVCの4.3.5.RELEASE
- 春のセキュリティ4.2.1.RELEASE
- のApache/2.4.6(CentOSの)
- のApache Tomcat/7.0.76
私もトークンCSRFを有効にしていますメソッドのために、そして要求をフィルターにかけることができます。セキュリティspring.xmlで設定
CsrfSecurityRequestMatcher.java(私はこれがこの問題のために重要である場合は知らない - これは必要ありませんであれば>は無視)
package com.XXX.YYY.config;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
public class CsrfSecurityRequestMatcher implements RequestMatcher {
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
// Deshabilitamos la protección CSRF de las siguientes URLs:
private AntPathRequestMatcher[] requestMatchers = { new AntPathRequestMatcher("/paypal/**") };
@Override
public boolean matches(HttpServletRequest request) {
if(allowedMethods.matcher(request.getMethod()).matches()){
return false;
}
// Si la peticion coincide con el patrón a ignorar deshabilitamos la protección CSRF
for (AntPathRequestMatcher rm : requestMatchers) {
if (rm.matches(request)) { return false; }
}
return true;
}
}