title: How to properly restrict access based on roles to API's with spring security?
body: <p>I want to secure my API's based on the user role, but @PreAuthorize Annotations seem to not work properly. No matter what role the user has the server throws a 403 error. How to make this work ? </p>
  
  <p>This is where I retrieve the User Details in my custom authentication provider:</p>
  
  <pre><code>   @Override
      protected UserDetails retrieveUser(String userName, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken){
          final String password = (String) usernamePasswordAuthenticationToken.getCredentials();
  
          if (!StringUtils.hasText(password)) {
              this.logger.warn("Username {}: no password provided", userName);
          }
  
          userName = parseCredentials(userName);
  
          try {
              DirContext ctx = ldapConfiguration.openConnection(userName, password);
              ctx.close();
          } catch (NamingException e) {
              throw new LdapException("User not found in Active Directory", e);
          } catch (NullPointerException e) {
              throw new CredentialsNotProvidedException("Entered data may be null", e);
          }
  
          User user = userRepository.findOneByLogin(userName);
  
          if (user == null) {
              this.logger.warn("Username {}: user not found", userName);
              throw new BadCredentialsException("Invalid Username/Password for user " + userName);
          }
  
          final List&lt;GrantedAuthority&gt; auths = new ArrayList&lt;GrantedAuthority&gt;();
  
          GrantedAuthority r = (GrantedAuthority) () -&gt; "ROLE_" + user.getRole().getName().toUpperCase();
          auths.add(r);
          // enabled, account not expired, credentials not expired, account not locked
          UserDetails userDetails = new org.springframework.security.core.userdetails.User(userName, password, true, true, true, true, auths);
          return userDetails;
      }
  </code></pre>
  
  <p>This is the controller:</p>
  
  <pre><code>@PreAuthorize("hasRole('ROLE_HR')") //I don't have acces even if I am HR
  @RestController
  public class SettingsController {
  
      @Autowired
      private LocationRepository locationRepository;
      @Autowired
      private DepartmentRepository departmentRepository;
      @Autowired
      private RoleRepository roleRepository;
  
      @RequestMapping(value = "/api/locations", method = RequestMethod.POST)
      public ResponseEntity addLocation(@RequestBody Location location) {
          if (location == null) {
              return new ResponseEntity(HttpStatus.BAD_REQUEST);
          }
          locationRepository.save(new Location(location.getName()));
          return new ResponseEntity(HttpStatus.CREATED);
      }
  
      @RequestMapping(value = "/api/roles", method = RequestMethod.POST)
      public ResponseEntity addRole(@RequestBody Role role) {
          if (role == null) {
              return new ResponseEntity(HttpStatus.BAD_REQUEST);
          }
          roleRepository.save(new Role(role.getName()));
          return new ResponseEntity(HttpStatus.CREATED);
      }
  
      @RequestMapping(value = "/api/departments", method = RequestMethod.POST)
      public ResponseEntity addDepartment(@RequestBody Department department) {
          if (department == null) {
              return new ResponseEntity(HttpStatus.BAD_REQUEST);
          }
          departmentRepository.save(new Department(department.getName()));
          return new ResponseEntity(HttpStatus.CREATED);
      }
  }
  </code></pre>
  
  <p>And security config:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private DatabaseAuthenticationProvider authenticationProvider;
  
      @Override
      public void configure(WebSecurity web) throws Exception {
          web.ignoring().antMatchers("/js/**", "/css/**", "/img/**");
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.formLogin().loginPage("/login").failureUrl("/login").defaultSuccessUrl("/")
                  .and().logout().logoutSuccessUrl("/login")
                  .and().authorizeRequests().antMatchers("/login").permitAll()
                  /*.antMatchers("/settings.html").access("hasRole('HR')")
                  .antMatchers("/pendingRequests.html").access("hasRole('MANAGER')")
                  .antMatchers("/settings.html","/pendingRequests.html").access("hasRole('ADMIN')")*/
                  .anyRequest().authenticated().and().csrf().disable();
      }
  
  
  
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth.authenticationProvider(authenticationProvider).eraseCredentials(false);
      }
  }
  </code></pre>