2016-05-25 60 views
0

我想用Spring Boot和AngularJS實現一個使用REST調用進行身份驗證的自定義登錄頁面。當我嘗試登錄時,POST方法正在被一個405方法不允許的響應拒絕。這就是我的設置。我已經設置了loginProcessingUrl並在登錄表單上設置了permitAll。除此之外,我基本上遵循this article的例子。這裏是我的設置:Spring Boot 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(); 
} 

存在的登錄頁面發送憑據對象,像這樣:{「用戶名」:「富」,「密碼」:「酒吧」}

編輯:添加角碼對於登錄

角服務

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

角度控制器在Angular服務中調用登錄函數,該服務發送$ http.post('/ api/authentication/login',憑證)。憑證對象如上所述,{用戶名,密碼}。 – nateha1984

+0

這是一個問題,但缺少問題代碼。 –

回答

0

「不允許的方法」也發生在你沒有在控制器中實現的某些HTTP方法。

由於您沒有向我們顯示控制器代碼,因此您可能會缺少@RequestMapping註釋的method屬性。

+0

我的理解是,Spring處理登錄請求並將用戶名和密碼傳遞給您正在進行身份驗證的服務。因此,我不需要單獨的登錄控制器,對嗎?如果需要,我添加了顯示驗證提供程序設置的代碼。 – nateha1984

+0

如果您使用Spring創建Web API,則很可能需要使用Spring MVC控制器。我指的是Spring MVC控制器,而不是角度控制器。 – luboskrnac

0

它耗盡了405錯誤是一個紅色的鯡魚。問題在於用戶名和密碼是作爲應用程序/ json請求發送的,而Spring Boot並不期望這個請求。當UsernamePasswordAuthenticationFilter試圖獲取用戶名時,它找不到它。我假設它然後通過該過濾器鏈的其餘部分,並以某種方式405錯誤是結果。

解決方案:擴展UsernamePasswordAuthenticationFilter以解析JSON對象,然後將這些憑證傳遞給身份驗證對象,如this post中所述。

相關問題