2016-05-02 14 views
0

私は認証のためにログインページを実装しています。 AngularJSは、ユーザーの資格情報を使用してサーバーに投稿要求を送信します。AngularJS:POST要求後にGETリクエストが返され、ログインのために302が返される

//service.js 
authApp.factory("loginFactory", function ($http) { 
    return{ 
     login: function(username, password) { 
      var data = {username: username, password: password}; 
      serialize = function(obj) { 
       var str = []; 
       for(var p in obj) 
       if (obj.hasOwnProperty(p)) { 
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 
       } 
       return str.join("&"); 
      } 

      return $http({ 
       method: 'POST', 
       url: 'http://localhost:8080/login', 
       data: serialize(data), 
       headers: { 
        'Content-Type': 'application/x-www-form-urlencoded', 
       } 
      }); 
     } 
    } 
}); 

以下のマイコンは、正常と異常を処理します。デバッグ目的のために、私はリダイレクトの代わりに応答を出力します。

authApp.controller('LoginCtrl', ['$scope', '$location', 'loginFactory', function($scope, $location, loginFactory){ 
    $scope.authenticate = function() { 
     loginFactory.login($scope.username, $scope.password) 
     .then(function(response) { 
      console.log(response); 
     }, function errorCallBack(response) { 
      console.log(response); 
     }); 
    } 
}]); 

私が実行すると、POST要求は応答なしで302を返します。そしてGETリクエストがすぐに始まります。パスワードが正しい場合は、 "http://localhost:8080/"にリダイレクトされます。パスワードが間違っていると、 "http://localhost:8080/login?error"にリダイレクトされます。どちらのパスにもハンドラがないので、401エラーが返されます。Angularコントローラは、GETリクエストからの応答をあたかもPostリクエストからの応答であるかのようにキャプチャします。

バックエンドでは、認証は春のセキュリティによって行わここでは、セキュリティの設定されています。

protected void configure(HttpSecurity http) throws Exception { 
     http 
      .httpBasic().and() 
      .addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class) 
      .csrf().disable() 
      .authorizeRequests() 
      .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() 
       .anyRequest() 
       .authenticated() 
       .and() 
      .formLogin(); 
       //.loginPage("/login"); 
    } 

どこGETリクエストから来たんなぜオリジナルのポスト要求はリダイレクトをトリガーん

答えて

1

GET要求は、サーバーによって返された302のためです。従来のフォームログインでは、springは次のようになります。

  1. 成功とエラーの場合の成功ページ(/)へのログイン
  2. リダイレクト用ハンドルポスト要求( '/ログイン?ERROR`)

ブラウザは透過的にリダイレクトを処理します。

春のデフォルトの動作を変更したい場合は、tutorialを参照することをお勧めします。このチュートリアルでは、フォームログインではなく基本認証を使用します。ただし、フォームのログインが必要な場合は、カスタム認証の成功と失敗ハンドラを実装する必要があります。以下のような何か:

セキュリティコンフィグ

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests().antMatchers("/login","/error").permitAll() 
      .anyRequest() 
      .fullyAuthenticated().and().formLogin() 
      .failureHandler(customAuthenticationFailureHandler).and() 
      .logout().logoutSuccessHandler(ajaxLogoutSuccessHandler); 
    http.exceptionHandling() 
      .authenticationEntryPoint(authenticationEntryPoint) 
      .accessDeniedHandler(customAccessDeniedHandler); 

} 

CustomAuthenticationFailureHandler失敗ハンドラのURLにステータスコード401の代わりに、リダイレクトを返します。

@Component 
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, 
     HttpServletResponse response, AuthenticationException exception) 
    throws IOException, ServletException { 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 

    } 

} 

AjaxLogoutSuccessHandler 401の代わりに、リダイレクトを返すようにページに

@Component 
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { 

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

    } 

} 

CustomAccessDeniedHandlerをログインする代わりにリダイレクトの401を返すように成功URL

@Component 
public class AjaxLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler 
     implements LogoutSuccessHandler { 

    @Override 
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, 
           Authentication authentication) 
      throws IOException, ServletException { 
     response.setStatus(HttpServletResponse.SC_OK); 
    } 
} 

CustomAuthenticationEntryPointをログアウトし、ステータス200の代わりに、リダイレクトを返すために拒否されたページにアクセスします。

@Component 
public class CustomAccessDeniedHandler implements AccessDeniedHandler { 

    @Override 
    public void handle(HttpServletRequest request, 
      HttpServletResponse response, 
      AccessDeniedException accessDeniedException) throws IOException, 
      ServletException { 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 

    } 

} 

これが役立ちます。

関連する問題