2016-04-13 9 views
4

私はSpring 4でExtjs-6を使ってアプリケーションを開発しています。私のアプリケーションは安らかです。
私は次のようにCORS起源を有効にします。Ext.Ajaxを使用してセキュリティを強化するにはどうすればよいですか?

public class CorsFilter extends OncePerRequestFilter { 

    private static final String ORIGIN = "Origin"; 


    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
     throws ServletException, IOException { 

     response.addHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Credentials", "true"); 
     response.addHeader("Access-Control-Max-Age", "10"); 

     String reqHead = request.getHeader("Access-Control-Request-Headers"); 

     if (!StringUtils.isEmpty(reqHead)) { 
      response.addHeader("Access-Control-Allow-Headers", reqHead); 
     } 

     if (request.getMethod().equals("OPTIONS")) { 
      try { 
       response.getWriter().print("OK"); 
       response.getWriter().flush(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     } else{ 
      filterChain.doFilter(request, response); 
     } 
    } 
} 

フィルターの設定:

<security:http use-expressions="true"> 
    ... 
    <sec:custom-filter ref="CorsFilter" before="HEADERS_FILTER"/> 
</security:http> 

とBean:

<bean id="CorsFilter" class="..." /> 

私はAJAX要求を持つユーザーのlogingにしたいです。私はAdvanced REST clienthttp requesterを使ってajaxリクエストをテストします。拡張の結果は以下の通りです:

enter image description here

enter image description here

内線Ajaxリクエストコードは以下の通りです:

Ext.Ajax.request({ 
    url: "http://localhost/Calk/j_spring_security_check", 
//  params: { 
//   "j_username": "ali", 
//   "j_password": "123456" 
//  }, 
    params: "j_username=ali&j_password=123456", 
    headers: { 
     "Content-Type": "application/x-www-form-urlencoded" 
    }, 
    method: "POST", 
    success: function(){...}, 
    failure: function(){...} 
}); 

私がリクエストを送信すると、それは200 OKを取得し、私はinitをクライアント側でアプリケーションを実行し、いくつかのデータを取得する要求を送信します。しかし、このすべての要求のサーバーは401 Unauthorizedになります。

問題点

重要な更新

Logining要求は以下の通りである:

enter image description here

Serverが応答にクッキーを設定し、に従うよう、許可取得のデータ要求は、次のとおりです。

enter image description here

なぜ

+0

'params:form.getValues()'を試しましたか? – qmateub

+0

はい、結果は上記と同じです。 –

+0

問題は、リクエストメソッド "OPTIONS"が使用され、認証に必要なパラメータがなくても常に送信されることです。 [その方法が使われている理由をここで確認](https://www.sencha.com/forum/showthread.php?95656-how-to-disable-Ajax.request-method-quot-OPTIONS-quot&p=452480&viewfull=1# post452480)。 – Alexander

答えて

1

を次のように春のセキュリティが動作します。
クライアントからのリクエストにJSessionIDクッキーがない場合、Springはそのクライアントのセッションをリセットし、無効なセッションを設定します。その次のリクエストはその無効なセッションとともに送信されます。

したがって、すべてのExt ajaxリクエストでCookieを設定する必要があります。私はいくつかの同時のajaxリクエストはクッキーを送信しないと思います。 は、Ajaxリクエストのすべてでクッキーを設定するためには、このイベントを追加することができます。

Ext.Ajax.on("beforerequest",function(con){ 
    con.setUseDefaultXhrHeader(false); 
    con.setWithCredentials(true); 
} 

この機能は、すべてのAJAXリクエストを送信する前に実行します。

2

エラーの原因は、クロスドメイン要求を行っているためです。私はあなたのアプリケーションサーバーが8084で動作している間、あなたのjavascriptアプリケーションが異なるポートで動作していると思います。

これを機能させるには、アプリケーションのCORSサポートを有効にする必要があります。ここでそれを行う方法があります。

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
     registry.addMapping("/**"); 
    } 
} 

Follow this link詳細については、ほとんどの場合、これはあなたのために働くはずです。もし、春のセキュリティがまだ苦しいならば、春のセキュリティのためにフィルタを追加する必要があるかもしれません。あなたは

<security:http use-expressions="true" .... > 
    ... 
    //your other configs 
    <sec:custom-filter ref="corsFilter" before="HEADERS_FILTER"/> 
</security:http> 

セキュリティ

用フィルター following this answer

public class CorsFilter extends OncePerRequestFilter { 

    private static final String ORIGIN = "Origin"; 


    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
     throws ServletException, IOException { 

     if (request.getHeader(ORIGIN) == null || request.getHeader(ORIGIN).equals("null")) { 
      response.addHeader("Access-Control-Allow-Origin", "*"); 
      response.setHeader("Access-Control-Allow-Credentials", "true"); 
      response.addHeader("Access-Control-Max-Age", "10"); 

      String reqHead = request.getHeader("Access-Control-Request-Headers"); 

      if (!StringUtils.isEmpty(reqHead)) { 
       response.addHeader("Access-Control-Allow-Headers", reqHead); 
      } 
     } 
     if (request.getMethod().equals("OPTIONS")) { 
      try { 
       response.getWriter().print("OK"); 
       response.getWriter().flush(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     } else{ 
      filterChain.doFilter(request, response); 
     } 
    } 
} 

設定によってビーン

<bean id="corsFilter" class="<<location of the CORS filter class>>" /> 
+0

私はいくつかの店舗を持っており、それらはすべて同じWebサーバーからデータを取得しています。しかし、ログイン要求だけが正しく動作しません。 –

+0

その後、セキュリティフィルターを試して、回答を更新してください。 – JChap

+0

あなたの回答に応じてコードを更新しました。ログインAjaxリクエストを送信すると、サーバーは '200 OK'を取得します(不正なユーザー/パスを送信すると、' 401 Authorized'が取得されます)。ユーザが正常にログインすると、いくつかのデータがajaxを使用して取得されますが、次のリクエストサーバでは '401 Authorized'が取得されます。 –

0

としてフィルターを公開することを行うことができます私はこの問題は、セッションクッキーは、のために設定されていることだと思います/Calk/パスであり、ajaxコールは/Workspace/Calk/から行われます。だから、セッションクッキーパスがSpringでどこで設定されているかを調べ、それをちょうど/に変更する必要があります。

私は春のセキュリティを使用していないが、クイック検索から thisthis問題は次の web.xmlでパスを変更することができますことを示唆しているように見える

<web-app> 
    <session-config> 
     <cookie-config> 
      <path>/</path> 
     </cookie-config> 
    </session-config> 
</web-app> 
関連する問題