gpt4 book ai didi

java - 使用 Spring Security for REST API 进行基本身份验证中的用户权限

转载 作者:行者123 更新时间:2023-11-30 06:25:11 28 4
gpt4 key购买 nike

我一直在尝试使用 Spring Security 通过基本身份验证来保护我的 Spring Rest API。我希望对其进行配置,以便将用户存储在数据库中,并且他们可以根据其角色访问不同的端点。为简单起见,在下面的示例中,所有端点都需要“ADMIN”角色。我认为我正确配置了所有内容(基于一些在线教程),但是安全性似乎无法处理比较我的用户权限(角色)。当我通过 postman 发送 GET 请求并使用用户名和密码进行授权时,找到了我的用户(我没有收到 401),但收到了 403,就好像用户没有适当的角色一样。如果我将 (hasRole(Role.ADMIN.name()) 更改为authentiated(),效果会很好。您能看一下我的代码并帮助我找出我缺少的内容吗?用户类别:

@Entity
@NoArgsConstructor
@Table(name = "users")
public class User implements UserDetails {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false, unique = true)
private String username;
private String password;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private Set<UserAuthority> authorities = new HashSet<UserAuthority>();

public User(String username, String password) {
this.username = username;
this.password = password;
}

public void addAuthority(UserAuthority authority) {
authorities.add(authority);
}

public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}

public String getPassword() {
return password;
}

public String getUsername() {
return username;
}

public boolean isAccountNonExpired() {
return true;
}

public boolean isAccountNonLocked() {
return true;
}

public boolean isCredentialsNonExpired() {
return true;
}

public boolean isEnabled() {
return true;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

public void setAuthorities(Set<UserAuthority> authorities) {
this.authorities = authorities;
}
}

用户权限类:

@Entity
@Table(name = "authorities")
@NoArgsConstructor
@Getter
@Setter
public class UserAuthority implements GrantedAuthority {
@Id
@GeneratedValue
private Long id;
private String name;

public UserAuthority(String name) {
this.name = name;
}

public String getAuthority() {
return name;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UserAuthority authority = (UserAuthority) o;

return name != null ? name.equals(authority.name) : authority.name == null;
}

@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
}

安全配置类:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

private static String REALM = "MY_TEST_REALM";
//to be a bean later
private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();
@Autowired
UserDetailsService userDetailsService;

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}

@Override
protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").hasRole(Role.ADMIN.name())
.and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint())
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
}

@Bean
public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
return new CustomBasicAuthenticationEntryPoint();
}

/* To allow Pre-flight [OPTIONS] request from browser */
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
}

UserServiceImpl 类的重要部分:

@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserRepository userRepository;

@Autowired
private UserAuthorityRepository userAuthorityRepository;
private PasswordEncoder passwordEncoder = new StandardPasswordEncoder();

public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return userRepository.getUserByUserName(s);
}
}

我得到的响应是 403:服务器理解该请求,但拒绝授权。

userRepository.getUserByUserName(s) 返回一个具有正确权限的正确 User 对象。

很抱歉,代码太多,我只是不知道错误可能出在哪里。非常感谢您的帮助!干杯

最佳答案

我解决了!结果角色必须使用前缀“ROLE_”进行持久化,因此我将其添加到我的角色枚举中:

private static final String ROLE_PREFIX = "ROLE_";

public String nameWithPrefix() {
return ROLE_PREFIX + name();
}

现在可以了:)

关于java - 使用 Spring Security for REST API 进行基本身份验证中的用户权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47316749/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com