2016-04-19 23 views
7

フロントエンドでReactjが使用され、バックエンドでSpringブートが使用されているRESTベースのWebアプリケーションをセットアップしようとしています。また、カスタム認証プロバイダをセットアップしようとしています。これが私の問題の始まりです。ログインAPI呼び出しをテストしようとすると、CustomAuthenticationProviderは呼び出されず、代わりにデフォルトのDaoAuthenticationProviderが使用されます。これにより、ログインで「Bad credentials」が報告されます。 spring-boot-auth-demoJavaのコンフィグレーションを使用したSpringブートカスタム認証プロバイダFIXED

を、私は、次のカールを使用してログインAPIをテストするには:

curl -H "Content-Type: application/json" -X POST -d '{"username":"admin","password":"admin"}' http://localhost:8080/api/users/login 

CustomAuthenticationProviderは、単純なユーザー名/パスワードのチェックを行い、UsernamePasswordAuthenicationTokenを返し、私はgithubのに小さなサンプルアプリケーションをアップロードしてい

オブジェクト。

package no.bluebit.demo; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.security.authentication.AuthenticationProvider; 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 
import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.stereotype.Component; 

import java.util.ArrayList; 
import java.util.List; 

@Component 
public class CustomAuthenticationProvider implements AuthenticationProvider { 

private static final Logger logger =  LoggerFactory.getLogger(CustomAuthenticationProvider.class); 

public CustomAuthenticationProvider() { 
    logger.info("*** CustomAuthenticationProvider created"); 
} 

@Override 
public Authentication authenticate(Authentication authentication) throws AuthenticationException { 

    if(authentication.getName().equals("admin") && authentication.getCredentials().equals("admin")) { 
     List<GrantedAuthority> grantedAuths = new ArrayList<>(); 
     grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); 
     grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN")); 
     return new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), grantedAuths); 
    } else { 
     return null; 
    } 

} 

@Override 
public boolean supports(Class<?> authentication) { 
    return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); 
} 

} 

CustomAuthenticationProviderは、SecurityConfigurationクラスを使用して配線されています。コードをステップ実行すると、CustomAuthenicationProviderが着信要求の認証に使用されたプロバイダのリストにないことがわかります。

package no.bluebit.demo; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
    @Autowired 
    private CustomAuthenticationProvider customAuthenticationProvider; 

    @Autowired 
    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
      .authenticationProvider(this.customAuthenticationProvider); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
       .antMatchers("/api/users/login").permitAll() // Permit access for all to login REST service 
       .antMatchers("/").permitAll()     // Neccessary to permit access to default document 
      .anyRequest().authenticated().and()     // All other requests require authentication 
      .httpBasic().and() 
      .logout().and() 
      .csrf().disable(); 
    } 
} 

なぜこれが機能しないのですか?

+1

これを見てください:http://stackoverflow.com/questions/22453550/custom-authentication-provider-not-being-called/22457561#22457561 – franDayz

+0

ありがとう!欠落した@Autowired注釈が問題でした。問題が解決しました! –

+0

@franDayzHåvardBakkeが答えとして受け入れることができるように、あなたのコメントを回答として追加することができますか? – demaniak

答えて

-1

AuthenticationProviderクラスを見た(それぞれ、それがJavaのドキュメントです)

方法の認証をすることを期待:

* Performs authentication with the same contract as 
* {@link org.springframework.security.authentication.AuthenticationManager#authenticate(Authentication)} 
* @return a fully authenticated object including credentials. May return 
* <code>null</code> if the <code>AuthenticationProvider</code> is unable to support 
* authentication of the passed <code>Authentication</code> object. In such a case, 
* the next <code>AuthenticationProvider</code> that supports the presented 
* <code>Authentication</code> class will be tried. 

あなたがnullを返す場合、次のAuthenticationProviderがdefautの一つである、と呼ばれます。

これが問題であるかどうかはわかりませんが、これは問題ではありません。 AuthenticationManagerクラスが指示するように、BadCredentialsExceptionをスローしてください。

* <li>A {@link BadCredentialsException} must be thrown if incorrect credentials are 
* presented. Whilst the above exceptions are optional, an 
* <code>AuthenticationManager</code> must <B>always</B> test credentials.</li> 
0

他の方法で資格情報を設定する必要があります。 Username Passwordトークンの実際の例を見てみましょう。しかし、あなたの "認証"機能は、資格情報を設定する機能である必要があります。

関連する問題