Spring OAuth2的checkUserScopes功能未按预期工作

18

首先,根据Spring文档,如果我想将用户角色映射到作用域,我应该使用setCheckUserScopes(true)来设置DefaultOAuth2RequestFactory。因此,一种方法是注入自己的DefaultOAuth2RequestFactory bean,正如文档所述:

The AuthorizationServerEndpointsConfigurer allows you to inject a custom OAuth2RequestFactory so you can use that feature to set up a factory if you use @EnableAuthorizationServer.

然后我执行

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends
        AuthorizationServerConfigurerAdapter {

    ...

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .tokenStore(tokenStore)
                .tokenServices(tokenServices());

       endpoints
            .getOAuth2RequestFactory(); // this doesn't return me my own DefaultOAuth2RequestFactory 

    }

    @Bean
    @Primary
    public OAuth2RequestFactory defaultOAuth2RequestFactory() {
        DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(
                clientDetailsService);
        defaultOAuth2RequestFactory.setCheckUserScopes(true);
        return defaultOAuth2RequestFactory;
    }
}

编辑

我忽略了AuthorizationServerEndpointsConfigurer中的requestFactory()方法。这是将它传递给Spring Security的正确方式。将OAuth2RequestFactory bean设置为主要的并没有起作用。我删除了一些内容,以便关注真正的问题:


在这个观察之后,实际的问题是:

据我所知,如果用户拥有A和B权限,而应用程序只有A范围,则他只会得到'A'范围。但事实并非如此。实际上发生的是,如果应用程序具有A范围,并且应用程序(而不是用户)拥有A和B权限,则用户获得A。但这毫无意义。

这是DefaultOAuth2RequestFactory方法解析用户范围的过程:

private Set<String> extractScopes(Map<String, String> requestParameters, String clientId) {
    ... // I avoid some unimportant lines to not make this post so long
    if ((scopes == null || scopes.isEmpty())) {
        scopes = clientDetails.getScope();
    }

    if (checkUserScopes) {
        scopes = checkUserScopes(scopes, clientDetails);
    }
    return scopes;
}

private Set<String> checkUserScopes(Set<String> scopes, ClientDetails clientDetails) {
    if (!securityContextAccessor.isUser()) {
        return scopes;
    }
    Set<String> result = new LinkedHashSet<String>();
    Set<String> authorities = AuthorityUtils.authorityListToSet(securityContextAccessor.getAuthorities());
    for (String scope : scopes) {
        if (authorities.contains(scope) || authorities.contains(scope.toUpperCase())
                || authorities.contains("ROLE_" + scope.toUpperCase())) {
            result.add(scope);
        }
    }
    return result;
} 

这是一个 bug 吗?如果我错了,请告诉我。谢谢。

1个回答

3
您需要通过代码类似于此处链接来连接您的OAuth2RequestFactory。
如果权限已由ClientDetailsService设置,则应该可以正常运行。如果您想要映射登录用户权限,我也在这里没有找到解决方法。

我显然忽略了requestFactory()方法,因此第一个“bug”可以通过通过该方法注入来解决。另一方面,我还没有找到第二个“bug”的解决方案。谢谢! - jscherman
我也很想了解后面的问题。也许@DaveSyer可以指导一下 :) - Stackee007
请 @DaveSyer,我们需要你的帮助 :) - jscherman
是的,这是我的。我在Jira上发布了它,他在Github上复制了这个问题。 - jscherman
我正准备自己打开Jira,突然看到了这个工单。很高兴你已经处理了。 - Stackee007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接