2016-08-22 89 views
-1

我想根据用户角色来保护我的API,但@PreAuthorize Annotations似乎无法正常工作。无论用户有什么作用,服务器都会抛出403错误。如何使这项工作?如何正确地限制基于角色的API访问Spring的安全性?

这是我取回我的自定义身份验证提供用户详细信息:

@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<GrantedAuthority> auths = new ArrayList<GrantedAuthority>(); 

     GrantedAuthority r = (GrantedAuthority)() -> "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; 
    } 

这是控制器:

@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); 
    } 
} 

和安全性配置:

@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); 
    } 
} 
+0

没有进行预授权工作,但任何用户访问任何这种way – Gustavo

+0

重新整理后它工作?并在类级别中删除它并添加到方法级别(但它应该位于requestmapping下的方法名称的顶部) –

回答

1

根据您在安全配置类中的注释行 .antMatchers("/settings.html").access("hasRole('HR')")用户角色是HR。

如果角色是HR那么你应该使用 @PreAuthorize("hasRole('HR')")

@PreAuthorize应该放在第一,然后提@RestController

@RestController 
@PreAuthorize("hasRole('HR')") 
public class SettingsController