Spring security Basic Authentication - 401 Unauthorized with correct credentials
Posted
技术标签:
【中文标题】Spring security Basic Authentication - 401 Unauthorized with correct credentials【英文标题】: 【发布时间】:2020-09-10 15:50:09 【问题描述】:这是我的安全配置类,我正在使用 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"
【问题讨论】:
你使用的用户是否有"USER"权限,尝试用authenticed()替换hasAuthority("USER") 将.hasAuthority("USER")
替换为.hasAuthority("ROLE_USER")
并确保将角色存储在数据库中为ROLE_ROLENAME
即ROLE_USER
@Ehab 您是否尝试过给出的答案?
【参考方案1】:
Spring Security 有ExpressionUrlAuthorizationConfigurer.java
,其方法如下。这里的前缀 ROLE_ 有所不同。
对于hasAuthority(), hasAnyAuthority()
方法,我们需要通过前缀ROLE_的权限,即ROLE_USER
对于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 + "')";
【讨论】:
以上是关于Spring security Basic Authentication - 401 Unauthorized with correct credentials的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 配置:Basic Auth + Spring Cloud Gateway
Spring Security应用开发(04)HTTP basic认证
为啥 Spring boot Security Basic Authentication 慢?
Spring boot security rest basic Authentication example
spring-boot Actuator 连同 Spring Security 和 Form Basic Auth
Spring security Basic Authentication - 401 Unauthorized with correct credentials