2016-05-25 16 views
0

私は、SpringブートとAngularJSでREST呼び出しを使用して認証するカスタムログインページを実装しようとしています。ログインしようとすると、POSTメソッドは405メソッドが許可されていない応答で拒否されています。ここに私のセットアップとして持っているものがあります。 loginProcessingUrlを設定し、ログインフォームにpermitAllを設定しました。それ以外は、基本的にはthis articleの例に従っています。ここに私の設定です:SpringブートloginProcessingUrl RESTサービス405メソッドが許可されていません

SecruityConfiguration.java

@Configuration 
@EnableGlobalMethodSecurity(securedEnabled = true) 
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Autowired 
Environment env; 
@Autowired 
private RESTAuthenticationEntryPoint authenticationEntryPoint; 
@Autowired 
private RESTAuthenticationFailureHandler authenticationFailureHandler; 
@Autowired 
private RESTAuthenticationSuccessHandler authenticationSuccessHandler; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .antMatchers("/webjars/**", "/modules/**", "/*.js") 
      .permitAll() 
      .anyRequest().authenticated() 
      .and() 
     .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) 
      .and() 
     .formLogin() 
      .permitAll() 
      .loginPage("/login") 
      .loginProcessingUrl("/api/authentication/login") 
      .successHandler(authenticationSuccessHandler) 
      .failureHandler(authenticationFailureHandler) 
      .and() 
     .logout() 
      .logoutUrl("/api/authentication/logout") 
      .logoutSuccessUrl("/login") 
      .and() 
     .csrf().csrfTokenRepository(csrfTokenRepository()) 
      .and() 
     .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class); 
} 
//Other code below... 

認証エントリポイント

@Component 
public class RESTAuthenticationEntryPoint implements AuthenticationEntryPoint { 

@Override public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) 
    throws IOException, ServletException { 

     httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
} 
} 

障害ハンドラー

@Component 
public class RESTAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { 

@Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) 
    throws IOException, ServletException { 

    super.onAuthenticationFailure(httpServletRequest, httpServletResponse, e); 
} 
} 

成功ハンドラ

@Component 
public class RESTAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { 

@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) 
    throws IOException, ServletException { 

    clearAuthenticationAttributes(request); 
} 
} 

私は、このセットアップで欠けているものを見ることができない、動作するはずと思われます。他のコードが必要な場合は、私が提供してくれることを喜んでします。助けてくれてありがとう!

編集:認証にActive Directory LDAPコードを追加する。コードはSecurityConfiguration.java

@Override 
public void configure(AuthenticationManagerBuilder auth) throws Exception { 
    ActiveDirectoryLdapAuthenticationProvider ldapAuthenticationProvider = 
      new ActiveDirectoryLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url")); 
    ldapAuthenticationProvider.setConvertSubErrorCodesToExceptions(true); 
    ldapAuthenticationProvider.setUseAuthenticationRequestCredentials(true); 
    ldapAuthenticationProvider.setUserDetailsContextMapper(userDetailsContextMapper()); 

    auth.authenticationProvider(ldapAuthenticationProvider); 
} 

@Bean 
public UserDetailsContextMapper userDetailsContextMapper() { 
    return new LDAPDetailsContextMapper(); 
} 

に存在するログインページが資格情報がそうのようなオブジェクトに送信:{ "ユーザ名": "foo" という、 "パスワード": "バー"}

編集:アンギュラコードを追加しますログインの

角度サービス

function login(credentials) { 
     var deferred = $q.defer(); 

     $http.post('/api/authentication/login', credentials) 
      .success(loginComplete) 
      .error(loginFailed); 

     // Promise for successful response. Return data to the controller 
     function loginComplete(data) { 
      user = data; 
      deferred.resolve(data); 
     } 

     // Promise for failed response. Logs error to console. 
     function loginFailed(err) { 
      deferred.reject(err, credentials); 
     } 

     // returns the promise 
     return deferred.promise; 

角度コントローラ

function login() { 
     var credentials = {username: vm.username, password: vm.password}; 

     if (validateRequiredFields()) { 
      authenticationService.login(credentials) 
       .then(loginSuccess) 
       .catch(loginFailed); 
     } 

     function loginSuccess(user) { 
      $rootScope.user = user; 

      //change route here 
      var redirectUrl = ''; 
      if ($location.search().redirect) { 
       redirectUrl = $location.search().redirect; 
      } else { 
       redirectUrl = '/'; 
      } 
      $location.url(redirectUrl); 
     } 
+0

どのようにログインしようとしましたかは非常に不明です。 MCVEを投稿することを検討してください。 –

+0

角度コントローラは、$ http.post( '/ api/authentication/login'、credentials)を送信するAngularサービスのログイン関数を呼び出します。資格証明オブジェクトは、上記のとおり、{ユーザー名、パスワード}です。 – nateha1984

+0

これは問題ですが、質問コードには記載されていません。 –

答えて

0

では、コントローラに実装され、特定のHTTPメソッドを持っていないときにも起こる「メソッドは許可されていません」。

コントローラコードを表示していないので、属性が@RequestMappingアノテーションでない可能性があります。

+0

私の理解では、Springはログインリクエストを処理し、認証しているサービスにユーザー名とパスワードを渡します。したがって、別のログインコントローラは必要ありません。必要な場合は、認証プロバイダの設定を示すコードを追加しました。 – nateha1984

+0

SpringでWeb APIを作成する場合は、Spring MVCコントローラを使用したいと考えています。私は、角度のないSpring MVCコントローラを指していました。 – luboskrnac

0

赤ちゃんが405エラーを実行しています。問題は、ユーザ名とパスワードが、Spring Bootが期待していなかったアプリケーション/ json要求として送信されたことでした。 UsernamePasswordAuthenticationFilterがユーザー名を取得しようとすると、ユーザー名を見つけることができませんでした。私は、その後、その例外をフィルタチェーンの残りの部分に渡し、どうにかして405エラーが発生したと仮定します。

解決策:UsernamePasswordAuthenticationFilterを拡張してJSONオブジェクトを解析し、this postで説明したように、これらの資格情報をAuthenticationオブジェクトに渡します。

関連する問題