我正在尝试将Spring安全性添加到我的Rest API并保护其中一个端点。我将实现UserDetails和RoleEntity的UserEntity添加到Rest API。它们存在于数据库中,并且用户具有角色:
public class UserEntity implements UserDetails {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name="id")
private String id;
private String name;
private String password;
@ManyToMany
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<RoleEntity> roles;
并覆盖UserDetails中的必要方法,并将它们设置为true。
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
for (RoleEntity role : getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
@Override
public String getUsername() {
return name;
}
@Override
public String getPassword() {
return password;
}
在扩展WebSecurityConfigurerAdapter的MyWebSecurityConfig中添加了配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/offences", "/offences/*", "/offences/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.httpBasic();
}
而且它也在工作。端点是安全的。但是当我在其他应用程序中硬编码一些用户(使用“管理员”用户名和密码)来发送请求时:
public HashMap<Boolean, Object> find(FindOffenceForm findOffenceForm) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setBasicAuth("admin", "admin");
HttpEntity<String> request = new HttpEntity<>(httpHeaders);
try {
ResponseEntity<String> responseEntity = restTemplate.exchange(URL_OFFENCE + "/find/" + findOffenceForm.getName(),
HttpMethod.GET, request, String.class);
result.put(true, objectMapper.readValue(responseEntity.getBody(), new TypeReference<Set<OffenceDTO>>() {
}));
} catch (Exception ex) {
result.put(false, ex.getMessage());
}
- 我得到401未经授权,在我的API中,我可以看到消息警告13660 o.s.s.c.bcrypt.bCryptPasswordEncoder:编码后的密码看起来不像BCrypt。在resttemaplete中发送请求时,我应该为BCrypt编码密码吗?*
编辑:好的,所以在我的数据库中,我没有为bcrypt编码密码。我更改了它,现在我得到403禁止。我添加到config .csrf().and().cors().disabled,但没有任何更改。
1条答案
按热度按时间dffbzjpn1#
我想你可能会看到403状态码,因为
ExpressionUrlAuthorizationConfigurer.AuthorizedUrl.hasRole(String role)
方法会自动将“ROLE_”前缀添加到字符串参数(请参阅此处的文档),所以过滤器链需要“ROLE_ADMIN”角色名称,而不仅仅是你传递给方法的“ADMIN”。如果你的RoleEntity.getRoles()
返回“ADMIN”、“USER”等没有任何前缀的角色名称,这种情况可能会发生。如果这就是原因,并且您不希望出现此默认行为,则有3种选择:
1.使用方法
.hasAuthority(String authority)
代替,如javadoc中所建议;1.在
UserEntity
类中重写getAuthorities()
方法中重写GrantedAuthority
创建逻辑。例如,像这样:
1.注册一个不带前缀的GrantedAuthorityDefaults类型的Bean,如下所示:
比如像这样。