title: Spring-boot security won't respect roles with custom AuthenticationProvider
body: <p>I am creating my own custom authentication provider. Right now i am just checking for a static username and password but later this will be replaced with something more advanced, so while i dont need to use a custom provider in this case that won't help me much since its just the ground work for additional code i havent added yet.</p>
  
  <p>With that said this is my code in its broken state.</p>
  
  <p>My custom authentication provider:</p>
  
  <pre><code>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 SatAuthenticationProvider implements AuthenticationProvider {
  
    private static final Logger LOGGER = LoggerFactory.getLogger(SatAuthenticationProvider.class);
  
    public SatAuthenticationProvider() {
      LOGGER.info("*** CustomAuthenticationProvider created");
    }
  
    @Override
    public boolean supports(Class&lt;? extends Object&gt; authentication) {
      return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
  
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  
      LOGGER.info("*** Creating authentication");
      if (authentication.getName().equals("test") &amp;&amp; authentication.getCredentials().equals("test")) {
        List&lt;GrantedAuthority&gt; grantedAuths = new ArrayList&lt;&gt;();
        grantedAuths.add(new SimpleGrantedAuthority("USER"));
        grantedAuths.add(new SimpleGrantedAuthority("ADMIN"));
        return new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), grantedAuths);
      } else {
        return null;
      }
  
    }
  }
  </code></pre>
  
  <p>Here is my security configuration that consumes is:</p>
  
  <pre><code>import com.comcast.iot.das.auth.SatAuthenticationProvider;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  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 DeviceSecurityConfig extends WebSecurityConfigurerAdapter {
  
    private static final Logger LOGGER = LoggerFactory.getLogger(SatAuthenticationProvider.class);
  
    @Autowired
    private SatAuthenticationProvider satAuthenticationProvider;
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      LOGGER.info("*** configuring http");
      http.authorizeRequests().anyRequest()
        .hasRole("USER")
        .and()
        .httpBasic();
    }
  
    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
      LOGGER.info("*** Setting builder");
      auth.authenticationProvider(this.satAuthenticationProvider);
    }
  }
  </code></pre>
  
  <p>Now when I run this if i use curl to hit an endpoint with no user and password specified I get the following:</p>
  
  <pre><code>% curl http://localhost:8080/molecule
  {
    "timestamp" : 1505925047977,
    "status" : 401,
    "error" : "Unauthorized",
    "message" : "Full authentication is required to access this resource",
    "path" : "/molecule"
  }
  </code></pre>
  
  <p>If I specify the correct username and password I get the following:</p>
  
  <pre><code>% curl -u test:test http://localhost:8080/molecule
  {
    "timestamp" : 1505925033015,
    "status" : 403,
    "error" : "Forbidden",
    "message" : "Access is denied",
    "path" : "/molecule"
  }
  </code></pre>
  
  <p>Finally if I specify the wrong username and password I get the following:</p>
  
  <pre><code>% curl -u test:test2 http://localhost:8080/molecule
  {
    "timestamp" : 1505925199406,
    "status" : 401,
    "error" : "Unauthorized",
    "message" : "No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
    "path" : "/molecule"
  }
  </code></pre>
  
  <p>One final point, while I cant get roles to work directly I can get it to test for if a user is authenticated at all and use it to give permission. This isnt a viable solution, as I need roles, but it may give anyone trying to answer this question some hints.</p>
  
  <p>So I can change the DeviceSecurityConfig class's configure method as follows:</p>
  
  <pre><code>  @Override
    protected void configure(HttpSecurity http) throws Exception {
      LOGGER.info("*** configuring http");
      http.authorizeRequests().anyRequest()
        .authenticated()
        .and()
        .httpBasic();
    }
  </code></pre>
  
  <p>With this new version of the code my curl requests do seem to at least work as expected (though there is no way to add roles in of course):. Here are the curl results with the code edit I just mentioned.</p>
  
  <p>No username and password:</p>
  
  <pre><code>% curl http://localhost:8080/molecule
  {
    "timestamp" : 1505925444957,
    "status" : 401,
    "error" : "Unauthorized",
    "message" : "Full authentication is required to access this resource",
    "path" : "/molecule"
  }
  </code></pre>
  
  <p>Incorrect password:</p>
  
  <pre><code>% curl -u test:test2 http://localhost:8080/molecule
  {
    "timestamp" : 1505925456018,
    "status" : 401,
    "error" : "Unauthorized",
    "message" : "No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
    "path" : "/molecule"
  }
  </code></pre>
  
  <p>The correct password and username using the following command now returns the full response form the endpoint I'd usually expect (omitted).</p>
  
  <pre><code>% curl -u test:test http://localhost:8080/molecule
  </code></pre>