【问题标题】:OAuth2 hasRole always return 401OAuth2 hasRole 总是返回 401
【发布时间】:2018-08-28 22:56:00
【问题描述】:

我尝试使用 OAuth2 创建 Spring Boot 应用程序。我创建的用户类定义如下:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@NotNull
private String username;

@NotNull
private String password;

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Role> roles;

我创建了具有 2 个角色的用户“test”:“USER”和“ADMIN”,但是当我想向“/get”处理程序发送 POST 请求时,我得到了 401 状态。 我的资源服务器配置:

@Autowired
private TokenStore tokenStore;

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources.resourceId("resource").tokenStore(tokenStore);
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/msg/**").authenticated()
        .antMatchers("/get/**").hasRole("ADMIN");
}

授权服务器配置 @自动连线 private AuthenticationManager authenticationManager;

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory().withClient("trustedClient")
        .authorizedGrantTypes("client_credentials","password")
        .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT")
        .scopes("read","write","trust")
        .accessTokenValiditySeconds(5000)
        .secret("secret");
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.pathMapping("/oauth/token", "/login")
        .tokenEnhancer(tokenEnhancer())
        .tokenStore(tokenStore())
        .authenticationManager(authenticationManager);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.checkTokenAccess("isAuthenticated()");
}

@Bean
public TokenEnhancer tokenEnhancer(){
    return new CustomTokenEnhancer();
}

@Bean
public TokenStore tokenStore(){
    return new InMemoryTokenStore();
}

自定义令牌增强器

@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
    User user = new User();
    user.setUsername(userDetails.getUsername());
    user.setPassword(userDetails.getPassword());
    List<Role> roles = new ArrayList<>();
    for(GrantedAuthority role: userDetails.getAuthorities())
        roles.add(new Role(role.getAuthority()));
    user.setRoles(roles);

    Map<String, Object> additional = new HashMap<>();
    additional.put("user", user);

    ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additional);
    return accessToken;
}

最后一个CustomUserDetails

public CustomUserDetails(User byUsername){
    this.username = byUsername.getUsername();
    this.password = byUsername.getPassword();

    List<GrantedAuthority> auths = new ArrayList<>();
    for(Role role: byUsername.getRoles())
        auths.add(new SimpleGrantedAuthority(role.getName().toUpperCase()));
    this.authorities = auths;
    System.out.println(this.authorities);
}

最后一个 println 返回 [USER, ADMIN]。

【问题讨论】:

    标签: java security spring-boot oauth-2.0 http-status-code-401


    【解决方案1】:

    如果您的配置正确,则默认情况下用户角色应具有“ROLE_”前缀。只需将此前缀添加到用户的角色,一切都应该有效。

    如果在此更改之后您仍然收到 401 状态,请尝试覆盖 application.properties (application.yml) 中的 oauth 过滤器顺序:

    security:
      oauth2:
        resource:
          filter-order: 3
    

    此问题与自 1.5 版本以来 spring oauth 的最新更改有关。请查看此链接https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#oauth-2-resource-filter

    【讨论】:

    • 我试过了,还是不行。我的用户现在拥有 ROLE_ADMIN 角色,但仍有 401
    • 没有改变,仍然是 401
    【解决方案2】:

    改变这部分:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/msg/**").authenticated()
        .antMatchers("/get/**").hasRole("ADMIN");
    }
    

    收件人:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/msg/**").authenticated()
        .antMatchers("/get/**").hasRole("ROLE_ADMIN");
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-28
      • 2016-05-22
      • 2018-04-03
      • 2016-06-14
      • 2020-08-28
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 2018-08-28
      相关资源
      最近更新 更多