Java Spring OAuth2 checkUserScopes未按预期工作

Java Spring OAuth2 checkUserScopes未按预期工作,java,spring,authentication,user-permissions,spring-security-oauth2,Java,Spring,Authentication,User Permissions,Spring Security Oauth2,首先,根据 ,如果要将用户角色映射到作用域,则应使用setCheckUserScopes(true)将其映射到DefaultOAuth2RequestFactory。一种方法是注入我自己的DefaultOAuth2RequestFactorybean,正如doc所说: The AuthorizationServerEndpointsConfigurer allows you to inject a custom OAuth2RequestFactory so you can use that f

首先,根据 ,如果要将用户角色映射到作用域,则应使用setCheckUserScopes(true)将其映射到DefaultOAuth2RequestFactory。一种方法是注入我自己的DefaultOAuth2RequestFactorybean,正如doc所说:

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;
    }
}

编辑 我忽略了AuthorizationServerEndpointsConfiger中的requestFactory()方法。这是将其传递给Spring Security的正确方法。将OAuth2RequestFactory bean设置为主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;
} 
private Set extractScopes(映射请求参数、字符串clientId){
…//为了不让这篇文章写得这么长,我避免了一些不重要的台词
if((scopes==null | | scopes.isEmpty()){
scopes=clientDetails.getScope();
}
if(检查用户范围){
scopes=checkUserScopes(scopes,clientDetails);
}
返回范围;
}
私有集合checkUserScopes(集合作用域、ClientDetails ClientDetails){
如果(!securityContextAccessor.isUser()){
返回范围;
}
设置结果=新建LinkedHashSet();
Set authorities=AuthorityUtils.authorityListToSet(securityContextAccessor.getAuthories());
for(字符串范围:范围){
if(authorities.contains(scope)| authorities.contains(scope.toUpperCase())
||authorities.contains(“角色\”+范围.toUpperCase())){
结果.增加(范围);
}
}
返回结果;
} 

这是虫子吗?如果我错了,请告诉我。关于

您需要通过代码连接OAuth2RequestFactory


如果当局已经确定,那么你应该是好的。如果您希望映射登录的用户权限I。

我显然忽略了requestFactory()方法,因此通过该方法注入它可以解决第一个“bug”。另一方面,我还没有找到任何解决第二个“bug”的方法。谢谢我也想知道后一个问题。可能是@DaveSyer会引导:)请@DaveSyer,我们需要你的帮助:)是的,是我的。我把它贴在了吉拉身上,他把这个问题复制到了吉图比身上,我正要打开吉拉,我看到了这张票。很高兴你这么做。