我想根据用户角色保护我的API,但@PreAuthorize Annotations似乎无法正常工作。无论用户具有什么角色,服务器都会抛出403错误。如何使这项工作?
这是我在自定义身份验证提供程序中检索用户详细信息的地方:
@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 :(得分:1)
根据安全配置类中的注释行
.antMatchers("/settings.html").access("hasRole('HR')")
用户角色是HR。
如果角色为 HR
,那么您应该使用
@PreAuthorize("hasRole('HR')")
并且@PreAuthorize
也应先放置,然后提及@RestController
@RestController
@PreAuthorize("hasRole('HR')")
public class SettingsController