2016-04-19 16 views
7

Sto provando a configurare un'applicazione web basata su REST, in cui il frontend utilizza Reactjs e il backend sta usando Spring Boot. Sto anche cercando di impostare un provider di autenticazione personalizzato, ed è qui che iniziano i miei problemi. Quando si tenta di verificare la chiamata dell'API di accesso, CustomAuthenticationProvider non viene mai chiamato e viene utilizzato il DaoAuthenticationProvider predefinito. Ciò causa il login per segnalare "Bad credentials".Spring Boot Provider di autenticazione personalizzato con configurazione Java FISSO

devo caricare una piccola applicazione di esempio per GitHub: spring-boot-auth-demo

Per provare l'API di accesso Io uso il seguente ricciolo:

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

Il CustomAuthenticationProvider fa un/controllo della password semplice nome utente e restituisce un UsernamePasswordAuthenicationToken oggetto.

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 è cablato utilizzando la classe SecurityConfiguration. Quando si passa attraverso il codice, posso vedere che CustomAuthenicationProvider non è nell'elenco dei provider utilizzati per autenticare la richiesta in entrata.

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(); 
    } 
} 

Perché non funziona?

+1

Dai un'occhiata a questo: http://stackoverflow.com/questions/22453550/custom-authentication-provider-not-being-called/22457561#22457561 – franDayz

+0

Grazie! L'annotazione @Autowired mancante era il problema. Problema risolto! –

+0

@franDayz potrebbe aggiungere il tuo commento come risposta, in modo che Håvard Bakke possa accettare come risposta? – demaniak

risposta

-1

un'occhiata alla classe AuthenticationProvider (rispettivamente è java doc)

Il metodo autenticazione prevede di:

* 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. 

Se si ritorna null, allora la prossima AuthenticationProvider sarà chiamato, che è il defaut uno .

Non sono sicuro che questo sia il problema, ma potrebbe essere qualcosa. Prova a gettare BadCredentialsException, come la classe AuthenticationManager ti dice di fare:

* <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

è necessario impostare le credenziali in qualche altro modo. Prova a vedere un esempio funzionante del token Password Username. Ma la tua funzione "autentica" deve essere quella che imposta le credenziali.

Problemi correlati