Search code examples
javaspringspring-bootspring-securitymicroservices

403 forbidden in Spring Security with Custom UserDetailsService only


I have following files in spring boot project for Spring Security. When I use inMemoryAuthentication it works but when I go with custom UserDetailsService it doesn't work. Custom UserDetailsService class gets called but still it gives 403 (when I am trying to access /user) but it works for open urls (/usr).

import org.springframework.security.core.userdetails.User

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //not using parameter which is being passed as trying to figure out the problem first.

        UserDetails user = User.withUsername("abc").password("abc").authorities("ADMIN").build();
        return user;
        
    }

}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
//      auth.inMemoryAuthentication().withUser("abc").password("abc").roles("ADMIN");
    }

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/api/user").hasRole("ADMIN")
        .antMatchers("/").permitAll()
        .and().formLogin();
    }

}
@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/usr")
    public ResponseEntity<String> getOpenResponse() {
        return ResponseEntity.ok("You are accessing open url");
    }

    @GetMapping("/user")
    public ResponseEntity<String> getSecuredResponse() {
        return ResponseEntity.ok("You are accessing secured path");
    }

}

What am I doing wrong here? Am I missing something?


Solution

  • The problem is here :

    UserDetails user = User.withUsername("abc").password("abc").authorities("ADMIN").build();
    

    You set your user’s authority to "ADMIN", but in SecurityConfig class you expect the user to have a role "ADMIN", which is, in fact, a shortcut for an authority of "ROLE_ADMIN" :

    http.authorizeRequests()
        .antMatchers("/api/user").hasRole("ADMIN")
    

    To solve the problem you should define the user’s role :

    User.withUsername("abc").password("abc").roles("ADMIN")