【发布时间】:2022-01-07 19:39:57
【问题描述】:
我正在从事 Spring Boot Security 项目,我在某些端点上进行了身份验证,以防止用户访问,并在我点击此 URL 时授予 ADMIN 权限:admin/users 我得到了登录页面,我输入了凭据而不是返回实际内容,而是返回 type=Forbidden, status=403
这是我的安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// inject spring user details interface
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/api/**" , "/").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and().formLogin();
}
@Bean
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
}
管理员用户控制器
@RestController
@RequestMapping("admin/users")
public class UserController {
//
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
// get all users
@PreAuthorize("hasAnyRole('ADMIN')")
@GetMapping
public List<User> getAllUsers(){
return userRepository.findAll();
}
// test
@PreAuthorize("hasAnyRole('ADMIN')")
@GetMapping("/test")
public String message() {
return "secured end point";
}
//create new users
@PreAuthorize("hasAnyRole('ADMIN')")
@PostMapping
public User registerUser(@RequestBody User user){
String password = user.getPassword();
String encodedPassword = passwordEncoder.encode(password);
user.setPassword(encodedPassword);
return userRepository.save(user);
}
}
用户详情
public class CustomUserDetails implements UserDetails {
/**
*
*/
private static final long serialVersionUID = 1256711395932122675L;
private User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
userDetailsService
[![@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
CustomUserDetail userDetail = null;
if(user != null) {
userDetail = new CustomUserDetail();
userDetail.setUser(user);
}
else {
throw new UsernameNotFoundException("user not exist with username " + username);
}
System.out.println("user details" + userDetail);
return userDetail;
}
}][2]][2]
【问题讨论】:
-
您的权威名称是什么?
ADMIN或ROLE_ADMIN如果是第一次使用hasAuthority而不是hasRole。 -
这里是我的 GrandAuthority 返回 user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
-
这并不能回答我的问题,数据库中有什么。
ADMIN或ROLE_ADMIN。如果您再次附加ROLE_,它将以ROLE_ROLE_ADMIN结尾,这也不正确。 -
oh ok 在数据库中 ii 有两个角色,ADMIN 和 USER
-
那么它应该可以工作,所以要么代码没有按照您的想法执行,要么您的角色不是您认为的那样。
标签: spring-boot spring-security