首页 > 解决方案 > 基于 Spring Boot 角色的身份验证不识别角色

问题描述

我有以下类并希望实现基于角色的身份验证,但它从不允许请求,因为它可能无法识别角色。这里可能存在什么问题?

用户实体

@Entity
@JsonIgnoreProperties(value = {"createdAt", "updatedAt", "roles", "enabled",
    "authorities", "credentialsNonExpired", "accountNonLocked", "accountNonExpired"})
@Data
@Accessors(chain = true)
public class User extends Base implements UserDetails {

@Size(min = 4, max = 20)
@NotNull
private String username;

//@Size(min = 4, max = 20)
@NotNull
private String password;

@NotNull
@Email
private String email;

@ElementCollection(fetch = FetchType.EAGER)
private List<Role> roles = new ArrayList<>();

@OneToMany
private List<Book> bookList = new ArrayList<>();

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return roles.stream().map((Role r) -> new SimpleGrantedAuthority(r.toFullString())).collect(Collectors.toList());
}

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {
    return true;
}
}

角色枚举

public enum Role {

ADMIN("ADMIN"),
USER("USER");

private final String text;

Role(final String text) {
    this.text = text;
}

@Override
public String toString() {
    return text;
}

public String toFullString() {return "ROLE_" + text;}
}

网络安全配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
JwtTokenProvider jwtTokenProvider;

@Autowired
UserService userService;

@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
    return super.authenticationManager();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().disable()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/actuator/**").hasAuthority(Role.ADMIN.toString())
            .antMatchers("/").permitAll()
            .antMatchers(HttpMethod.DELETE,"/user/remove").hasAnyAuthority(Role.ADMIN.toString(), Role.USER.toString())
            .antMatchers(HttpMethod.PUT, "/user/create").permitAll()
            .antMatchers(HttpMethod.POST, "/signin").permitAll()
            .antMatchers("/admin/**").hasAuthority(Role.ADMIN.toString())
            .and()
            .apply(new JwtConfig(jwtTokenProvider));
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("admin")
            .password(bCryptPasswordEncoder().encode("abcd123"))
            .roles(Role.ADMIN.toString());
    auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("HEAD");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("PATCH");
    source.registerCorsConfiguration("/**", config);
    return source;
}

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}
}

这就是我设置新用户角色的方式

@Transactional
public GenericResponse create(UserDTO userDTO) {
    if (usernameExists(userDTO.getUsername())) {
        throw new UsernameExistsException(String.format("Username %s already exists", userDTO.getUsername()));
    }

    User user = modelMapper.map(userDTO, User.class);
    user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()))
            .setRoles(Arrays.asList(Role.USER, Role.ADMIN))
            .setId(UUID.randomUUID().toString());

    if (userRepository.save(user) != null) {
        return genericResponseService.createResponseNoError(user);
    } else throw new RuntimeException();
}

我正在为我之前创建的用户发送 /user/remove 请求。如上所示,新生成的用户始终具有 USER 角色。

控制器

@RestController
@RequestMapping("user")
public class UserController {

@Autowired
UserService userService;

@PutMapping(value = "create", consumes = "application/json")
public GenericResponse create(@Valid @RequestBody UserDTO userDTO) {
    return userService.create(userDTO);
}

@DeleteMapping(value = "remove", consumes = "application/json")
public GenericResponse remove(@Valid @RequestBody UserDTO userDTO) {
    return userService.remove(userDTO);
}
}

标签: javaspring-bootroles

解决方案


推荐阅读