Spring OAuth2.0:基于ClientId(授权代码授予类型)获取用户角色

时间:2019-05-28 08:50:41

标签: spring-boot jwt spring-security-oauth2

我有一个用于AuthServer的spring boot OAuth设置,它可用于使用spring-security-jwt为许多少数资源服务器提供身份验证。 我的问题是在进行身份验证时,我需要加载用户角色,但特定于clientId。 例如:如果user1具有角色client1的ROLE_A,ROLE_B和client2的ROLE_C,ROLE_D,则当用户使用client1或client2登录时,他可以看到所有四个角色。 ROLE_A,ROLE_B,ROLE_C,ROLE_D,因为我正在根据用户名获取角色。 如果我需要基于客户端的角色,则需要clientId。 仅供参考 我正在使用授权代码流进行身份验证。 我看到过类似的问题,但这是基于密码授予的,但是我正在尝试授权代码流,但是该解决方案对我不起作用。 密码授予问题link

以下是我需要clientId
的代码 MyAuthenticationProvider.java

@Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        String userName = ((String) authentication.getPrincipal()).toLowerCase();
        String password = (String) authentication.getCredentials();
        String clientId = ? // how to get it
        ....
    }
}

MyUserDetailsS​​ervice.java

@Override
    public UserDetails loadUserByUsername(String username) {
        String clientId = ? // how to get it 
        ....
    }
}

3 个答案:

答案 0 :(得分:0)

您可能需要在Spring-security中查看OAuth2Authentication。当您的客户端通过oauth2进行身份验证时,您的“身份验证”实际上就是最终实现身份验证的OAuth2Authentication实例。

如果您看到OAuth2Authentication的实现,则按以下步骤完成;

    public Object getPrincipal() {
       return this.userAuthentication == null ? this.storedRequest.getClientId() : this.userAuthentication
            .getPrincipal();
    }

因此,如果请求中包含“ clientId”,则只要您的请求中不包含用户身份验证,就应该能够通过调用getPrincipal()并将类型转换为String来获取clientId。

对于第二种情况,用户名实际上被视为clientId。您需要调用内存中的RDBMS或任何存储了clientId并返回ClientDetails的实现。通过查看Spring安全性的ClientDetailsUserDetailsS​​ervice类,您将可以有所了解。

答案 1 :(得分:0)

由于我没有得到任何适合自己问题的解决方案,因此我将发布在挖掘源代码和研究后使用的解决方案。
MyJwtAccessTokenConverter.java (扩展JwtAccessTokenConverter并实现增强方法)

public class OAuthServerJwtAccessTokenConverter extends JwtAccessTokenConverter {
....
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
    String clientId = authentication.getOAuth2Request().getClientId();
    // principal can be string or UserDetails based on whether we are generating access token or refreshing access token
    Object principal = authentication.getUserAuthentication().getPrincipal();
    ....
    }
....
}

信息:
在增强方法中,我们将从 authentication.getOAuth2Request()获取clientId,并从 authentication.getUserAuthentication()获得userDetails / user_name。
与JwtAccessTokenConverter一起,在生成访问令牌步骤和刷新令牌步骤时,分别需要AuthenticationProvider和UserDetailsS​​ervice进行身份验证。

答案 2 :(得分:0)

从请求中获取授权标头,然后从base64进行解析以获取客户端ID。

类似这样的东西:

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes())
.getRequest();
String authHeader = request
.getHeader("Authorization");