Spring Security基本身份验证-401未经授权使用正确的凭证

时间:2020-05-23 20:25:06

标签: java spring spring-boot spring-security basic-authentication

这是我的安全性配置类,我正在使用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);
    }
}

这是我对UserDetailsS​​ervice的实现

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表中的用户名和密码的地方。

现在,当我可以使用刚刚添加的用户名和密码使用邮递员调用GET方法时,出现如下所示的401未经授权错误

{
    "timestamp": "2020-05-23T20:12:10.165+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/api/auth/resources"
}

1 个答案:

答案 0 :(得分:0)

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 + "')";
}