spring-bootspring-securityspring-data-jpaspring-security-rest

Spring Custom Security With MySQL And JPA Giving 403 Access Denied


I am trying to access my rest api on postman by providing authentication using UserDetailsService, but each time I am firing the request every time request giving 403 Access Denied. The behavior is same for POST and GET method. I have read the other issues logged on forum but every answers says it is due to CSRF, I disabled it but issue remains same.

Complete code is on : https://github.com/afulz29/spring-security-demo.git

Please help me, I am struggling with this issue since 3 days.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer{

@Autowired
UserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .userDetailsService(userDetailsService)
        .passwordEncoder(passwordEncoder());
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http
        .authorizeRequests()
            .antMatchers("/api/**").authenticated().anyRequest().hasAnyRole("ADMIN");
}

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedMethods("*");
}
}



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

@Autowired
private UserService userService;

@GetMapping(path = "/users")
public User getUserById(@RequestParam("userId") Integer userId) {
    return userService.getUserById(userId);
}

@PostMapping(path = "/users", consumes = MediaType.APPLICATION_JSON_VALUE)
public User addUser(@RequestBody User user) {
    return userService.addUser(user);
}
}

Postman request


Solution

  • I see couple of problems with your security config:

    1. BASIC AUTH is not enabled but you are trying to do Basic Auth in postman

    Do the following to enable Basic Auth

            http
                .authorizeRequests()
                    ...
                    .and()
                    .httpBasic();
    
    1. I guess the POST /api/users is a user registration endpoint. You must whitelist this endpoint so that anyone can register
            http
                .authorizeRequests()
                        .antMatchers( HttpMethod.POST,"/api/users").permitAll()
                        .antMatchers("/api/**").authenticated()
                        .anyRequest().hasAnyRole("ADMIN")
                    .and()
                        .httpBasic();
    

    Test:

    Create user

    POST: localhost:8080/api/users
    
    {
            "userName" : "user1",
            "password": "pass"
    }
    

    Get user info

    
    GET: localhost:8080/api/users?userId=1   //use the correct ID
    
    With Basic Auth: userName = user1, password = pass
    
    

    BONUS Feedback:

    1. User.userName --> you might want to make this field unique
    2. @Repository this annotation is not required in your Repository interfaces
    3. UserService interface. I don't see any reason to use the interface and impl.