Spring Boot custom authentication provider with Java configuration not working

I am trying to configure a REST-based web application in which the front end uses Reactjs and the backend uses Spring Boot. I am also trying to set up a custom authentication provider, and this is where my problems begin. When trying to verify the login API call, the CustomAuthenticationProvider is never called, but instead the standard DaoAuthenticationProvider is used. This causes the login to report "Bad credentials."

I downloaded a small sample application on github: spring-boot-auth-demo

To check the login API, I use the following curl:

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

CustomAuthenticationProvider performs a simple username and password verification and returns a UsernamePasswordAuthenicationToken object.

 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 is connected using the SecurityConfiguration class. When viewing the code, I see that CustomAuthenicationProvider is not in the list of providers used to authenticate the incoming request.

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

Why is this not working?

+9
java spring authentication rest spring-security
source share
3 answers

Try adding to the http header this thinks:

Example:

 const headers = new HttpHeaders(); headers.set('Access-Control-Allow-Origin', '*'); headers.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT'); headers.set('Access-Control-Allow-Headers', 'Authorization, Content-Type, Accept, x- requested-with, Cache-Control'); headers.set('Content-Type', 'application/json'); this.http.post('http://localhost:8081/loginAngular', JSON.stringify({user: 'sdasd', password: 'dasdasd', estado: 'dasdasd', idUsuario: 1, resultado: 'asdasd'}) , {headers: new HttpHeaders().set('Content-Type', 'application/json')}).subscribe(data => { console.log(' Data: ' + data); }); 

I made this application with spring safety and angular! Front: https://github.com/nicobassart/angularforHidra Back: https://github.com/nicobassart/hidra_server

0
source share

Look at the AuthenticationProvider class (this is java doc, respectively)

Method confirmation pending:

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

If you return zero, then the next AuthenticationProvider will be called, which is defaut one.

I'm not sure if this is a problem, but it could be something. Try to throw a BadCredentialsException, as the AuthenticationManager class says:

  * <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> 
-one
source share

You must set the credentials in some other way. Try to see a working example of a username token. But your authentication function should be the one that sets up the credentials.

-one
source share

All Articles