java - Spring security Basic Authentication - 401 Unauthorized with correct credentials
问题描述
这是我的安全配置类,我正在使用 BCryptPasswordEncoder
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder encoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.POST,"/api/auth/register")
.permitAll()
.antMatchers(HttpMethod.GET,"/api/auth/resources")
.hasAuthority("USER")
.and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
}
这是我对 UserDetailsService 的实现
public class UserDetailsServiceImpl implements UserDetailsService{
@Autowired
private AccountRepository repo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account account = repo.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("No user found for username " + username));
User user =
new User(account.getUsername(), account.getPassword(), true, true, true, true, AuthorityUtils.createAuthorityList(account.getAuthorities()));
return user;
}
}
上面的 POST 方法是我可以提供存储在 MySQL 表中的用户名和密码的地方。
现在,当我可以使用 Postman 使用刚刚添加的用户名和密码调用 GET 方法时,我会收到如下所示的 401 Unauthorized 错误
{
"timestamp": "2020-05-23T20:12:10.165+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/api/auth/resources"
}
解决方案
Spring Security 具有ExpressionUrlAuthorizationConfigurer.java
以下方法。这里前缀ROLE_ 有所作为。
对于
hasAuthority(), hasAnyAuthority()
方法,我们需要使用前缀ROLE_来传递权限,即ROLE_USER
for
hasRole()
方法自动添加前缀ROLE_,因此我们只能将权限名称传递为USER
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
if (role.startsWith("ROLE_")) {
throw new IllegalArgumentException("role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
} else {
return "hasRole('ROLE_" + role + "')";
}
}
private static String hasAuthority(String authority) {
return "hasAuthority('" + authority + "')";
}
private static String hasAnyAuthority(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','");
return "hasAnyAuthority('" + anyAuthorities + "')";
}
推荐阅读
- arrays - 如何在 VBA 中引用变量矩阵中的整列或整行?
- browser - 当浏览器重新加载资源时,如果用户不强制清除缓存(例如 Ctrl + F5)
- powerbi - 创建的列未按预期计算
- java - while循环有问题并且没有得到预期的输出?
- google-chrome - 如何在 Chrome 中编辑 HSTS“max-age”指令?
- angular - npm 错误!awesome-typescript-loader@4.0.0-0 安装后
- docker - 在容器之间共享 Docker 容器存储卷
- mysql - 根据子模型/关系对父模型进行排序
- amazon-cognito - 通过 SPA 使用 aws amplify 的安全方式
- java - 如何在 UI 中搜索带有 '\t \n \r' 字符的文本