0

I have a spring boot application where I want to secure different endpoints with different credentials. I think roles are the best (only?) way to implement this and have written:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
  private static final String ROLE_1 = "role1";
  private static final String ROLE_2 = "role2";

  @Autowired
  private MyBasicAuthenticationEntryPoint authenticationEntryPoint;

  @Override
  protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
            
    auth.inMemoryAuthentication()
        .withUser("user1").password(passwordEncoder().encode("user1Pass")).roles(ROLE_1)
        .and()
        .withUser("user2").password("user2Pass").roles(ROLE_2);
    }
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
  
    http.csrf().disable().authorizeRequests().antMatchers("/endpoint1").hasRole(ROLE_1)
                                             .antMatchers("/endpoint2").hasRole(ROLE_2)
                                             .antMatchers("/").permitAll().and().httpBasic()
                                             .authenticationEntryPoint(authenticationEntryPoint);

    http.headers().frameOptions().disable();
  }
  
  @Bean 
  public PasswordEncoder passwordEncoder() { 
      return new BCryptPasswordEncoder(); 
  }
}

But when I call either endpoint (with the credentials from configure) I get 401 Unauthorized. Why are the credentials I specify in configure not accepted?

peer
  • 4,171
  • 8
  • 42
  • 73
  • also to find out such stuff learn how to activate debug logs in spring security https://stackoverflow.com/a/47729991/1840146 – Toerktumlare Jan 18 '21 at 12:18

1 Answers1

0

Because you are telling spring that the generated hash is the password. And not your password, so it gets double hashed.

.password(passwordEncoder().encode("user1Pass"))

if you look in the official documentation it shows you how you should construct your user, you should be using the withDefaultPasswordEncoder and spring will hash the password for you.

User user = User.withDefaultPasswordEncoder()
  .username("user")
  .password("password")
  .roles("user")
  .build();
System.out.println(user.getPassword());

Remember that setting up users this way should only be done for tests, and never production, thats why withDefaultPasswordEncoder is deprecated in the official api.

Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
  • Thanks, I'll take a closer look at this later. Upfront: I don't use a hash for user2 and that doesn't work either, so I think there is something else wrong – peer Jan 18 '21 at 13:45