2011-02-10 14 views

答えて

10

これを実行する最も簡単な方法は、AJAXリクエストのURLにフィルタを使用することです。

例で

私はちょうどセッションタイムアウトを示す応答本体とHTTP 500応答コードを送信してい下回っていますが、簡単にあなたのケースのために、より適しているものに応答コードと体を設定することができます。..

package com.myapp.security.authentication; 

import org.springframework.web.filter.GenericFilterBean; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

public class ExpiredSessionFilter extends GenericFilterBean { 

    static final String FILTER_APPLIED = "__spring_security_expired_session_filter_applied"; 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 

     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (request.getAttribute(FILTER_APPLIED) != null) { 
      chain.doFilter(request, response); 
      return; 
     } 

     request.setAttribute(FILTER_APPLIED, Boolean.TRUE); 
     if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {    
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SESSION_TIMED_OUT"); 
      return; 
     } 

     chain.doFilter(request, response); 
    } 
} 
+0

これはどこでBean設定ファイルに追加しますか?私はこれを以前に試して、それに問題がありました。初めて正しく設定したかどうかはわかりません。これは正しい軌道にあるようだ。 –

+0

Spring Securityが適切に設定されていると仮定すると、applicationContext-security.xmlのセキュリティフィルタチェーンにこのフィルタを追加するだけです:フィルタを_ _として定義し、_ _ –

+0

あなたの意見では、このフィルターを他のフィルターに注入するのに最適な場所は何ですか?カスタムフィルタ属性には、フィルタが組み込まれた前後のフィルタ属性があります。http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-custom-filters 。私はそれがajaxを介してすべてのページ上で実行されることを望んでいないが、管理セクションのように確保されているページでのみ。私は間違いなくそれが今すぐフィルターを打つことを持っている、それはthosrのセキュリティで保護されたページ上で実行されていることを確認する必要があります。その後、あなたは私からANSWERチェックを受けました! –

3

私は考えているアプローチは非常に簡単です。このサイトで私が見たアプローチの組み合わせです。 http://yoyar.com/blog/2012/06/dealing-with-the-spring-security-ajax-session-timeout-problem/

基本的な考え方は、上記のように、認証エントリポイントとともにapi url接頭辞(つまり/ api/secured)を使用することです。シンプルで機能します。

は、ここでの認証エントリポイントです:

package com.yoyar.yaya.config; 

import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; 

import javax.servlet.ServletException; 
import javax.servlet.http.*; 
import java.io.IOException; 

public class AjaxAwareAuthenticationEntryPoint 
      extends LoginUrlAuthenticationEntryPoint { 

    public AjaxAwareAuthenticationEntryPoint(String loginUrl) { 
     super(loginUrl); 
    } 

    @Override 
    public void commence(
     HttpServletRequest request, 
     HttpServletResponse response, 
     AuthenticationException authException) 
      throws IOException, ServletException { 

     boolean isAjax 
      = request.getRequestURI().startsWith("/api/secured"); 

     if (isAjax) { 
      response.sendError(403, "Forbidden"); 
     } else { 
      super.commence(request, response, authException); 
     } 
    } 
} 

そしてここでは、あなたの春のコンテキストXMLで行くものです:

<bean id="authenticationEntryPoint" 
    class="com.yoyar.yaya.config.AjaxAwareAuthenticationEntryPoint"> 
    <constructor-arg name="loginUrl" value="/login"/> 
</bean> 

<security:http auto-config="true" 
    use-expressions="true" 
    entry-point-ref="authenticationEntryPoint"> 
    <security:intercept-url pattern="/api/secured/**" access="hasRole('ROLE_USER')"/> 
    <security:intercept-url pattern="/login" access="permitAll"/> 
    <security:intercept-url pattern="/logout" access="permitAll"/> 
    <security:intercept-url pattern="/denied" access="hasRole('ROLE_USER')"/> 
    <security:intercept-url pattern="/" access="permitAll"/> 
    <security:form-login login-page="/login" 
         authentication-failure-url="/loginfailed" 
         default-target-url="/login/success"/> 
    <security:access-denied-handler error-page="/denied"/> 
    <security:logout invalidate-session="true" 
        logout-success-url="/logout/success" 
        logout-url="/logout"/> 
</security:http> 
1

私は、バックエンドで@Mattによって同じ溶液を使用しています。フロントエンドでangularJsを使用している場合は、以下のインターセプタを角$ httpで追加して、ブラウザが実際にログインページにリダイレクトするようにします。

var HttpInterceptorModule = angular.module('httpInterceptor', []) 
.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('myInterceptor'); 
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; 
}) 
.factory('myInterceptor', function ($q) { 
return { 
    'responseError': function(rejection) { 
     // do something on error 
     if(rejection.status == 403 || rejection.status == 401) window.location = "login"; 
     return $q.reject(rejection); 
    } 
    }; 

});

バージョン1.1.1後AngularJsを使用している場合のみ、線の下に必要であることに注意してください(angularJSは、以降そのバージョンからヘッダ「X-要求-で」を削除)のすべてのように見て

$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; 
1

現在の答えは、私は現在、春のブートRESTアプリケーションで作業している私の解決策を共有しましょう、ここ数年の古い:

@Configuration 
@EnableWebSecurity 
public class UISecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     ... 
     http.exceptionHandling.authenticationEntryPoint(authenticationEntryPoint()); 
     ... 
    } 

    private AuthenticationEntryPoint authenticationEntryPoint() { 
     // As a REST service there is no 'authentication entry point' like MVC which can redirect to a login page 
     // Instead just reply with 401 - Unauthorized 
     return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); 
    } 
} 

ここで基本的な前提は、私​​は、デフォルトでた認証エントリポイントをオーバーライドすることです存在しないログイン・ページにリダイレクトを発行するe。これは、401を送信することで応答します。Springは暗黙的に、それが返す標準エラー応答JSONオブジェクトも暗黙的に作成します。

関連する問題