我使用 DaoAuthenticationProvider
使用Spring Security进行基本身份验证 . 我想预先授权我的请求,所以我使用 @PreAuthorize
注释 . 问题是,Spring Security似乎没有区分多个角色和权限 . 例如,如果我访问 /users
,系统会提示我登录界面,但无论我登录的是哪个用户,我都会显示所有用户的列表 . 这不是我想要实现的,我想限制用户列表访问角色admin .
这是我的 SecurityConfig
:
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Resource(name = "userRestClient")
UserService userService;
@Autowired
private AuthenticationProvider authenticationProvider;
@Autowired
@Qualifier("authenticationProvider")
public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) {
this.authenticationProvider = authenticationProvider;
}
@Autowired
public void configureAuthManager(AuthenticationManagerBuilder authenticationManagerBuilder) {
authenticationManagerBuilder.authenticationProvider(authenticationProvider);
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userService);
// authProvider.setPasswordEncoder(encoder());
return authProvider;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeRequests()
.antMatchers("/", "/users", "/user").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout().permitAll();
httpSecurity
.csrf().disable();
httpSecurity
.headers()
.frameOptions().disable();
}
@Bean
protected UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
这是我的控制器:
@Controller
@Component
public class UserWebController {
private final UserRestClient userService = new UserRestClient();
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users", method = RequestMethod.GET)
@Produces(MediaType.APPLICATION_JSON)
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAllUsers().stream().map(UserMapper.INSTANCE::from).collect(Collectors.toList());
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}
}
我的 UserDetails
接口的实现:
public class MyUser implements UserDetails {
private User user;
public MyUser(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> roles = new HashSet<>();
roles.add(new Authority(user.getRole()));
return roles;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
用户实体:
@Table(name = "users")
@AllArgsConstructor
@Data
@NoArgsConstructor
@javax.persistence.Entity
public class User extends Entity implements Serializable {
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "role")
private String role;
}
1 回答
您必须启用
@PreAuthorize
,请参阅EnableGlobalMethodSecurity#prePostEnabled:您修改和简化的配置: