首页 文章

Spring Security不区分角色

提问于
浏览
-1

我使用 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 回答

  • 0

    您必须启用 @PreAuthorize ,请参阅EnableGlobalMethodSecurity#prePostEnabled

    确定是否应启用Spring Security的预发布注释 . 默认值为false .

    您修改和简化的配置:

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true, 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);
            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()
                    .and()
                .csrf()
                    .disable()
                    .and()
                .headers()
                    .frameOptions().disable();
        }
    
        @Bean
        protected UserDetailsService userDetailsService() {
            return super.userDetailsService();
        }
    }
    

相关问题