在JWT Grant中,如何将JWT令牌中包含的授权声明与与交换的访问令牌相关的范围相关联?

时间:2018-12-21 10:20:45

标签: wso2 wso2-am

这是我完成该集成的最后一部分:

  • 我有一个生成JWT令牌的外部身份提供商。这些令牌包含声明“ auth”,其中包含用户的权限,例如:"auth" : [ "editor", "reviewer"]

  • 在WSO2中,我有一个 API,在其某些端点中需要“编辑器”作用域

  • 我正在使用JWT Grant将来自外部IP的JWT交换为WSO2访问令牌以调用API。

我需要WSO2在创建访问令牌时将其与JWT的“ auth”声明中包含的范围相关联。

这可能吗?有扩展点可以实现吗?

2 个答案:

答案 0 :(得分:1)

应该可以通过扩展JWT授权类型并覆盖validateScope方法来实现。您可以从JWT检索范围并将其设置为tokReqMsgCtx。然后,您应该可以像下面这样设置setScopes。

@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
    // Create scopes array
    // String scopes[] = getScopesFromJWT();
    tokReqMsgCtx.setScope(scopes);
    return true;
}

例如,看看如何针对SAML2承载授权类型[1]完成此操作。

如果使用的是JWT授权类型,则在“ repository / conf / identity / identity.xml”文件的SupportedGrantTypes部分中进行配置。配置中提到了相关的GrantTypeHandlerImplClass。

<SupportedGrantType>
    <GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName
    <GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>
    ....
</SupportedGrantType>

有关编写自定义授予类型的信息,请参阅文档[2]。

[1] https://github.com/wso2/carbon-apimgt/blob/6.x/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/ExtendedSAML2BearerGrantHandler.java

[2] https://docs.wso2.com/display/IS560/Writing+a+Custom+OAuth+2.0+Grant+Type

答案 1 :(得分:1)

这就是我最终解决扩展JWTBearerGrantHandler的方式:

public class JWTBearerGrantHandlerJWTAuthAware extends JWTBearerGrantHandler {

    private static final Log LOG = LogFactory.getLog(JWTBearerGrantHandlerJWTAuthAware.class);

    @Override
    public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {

        LOG.debug("validateScope()");
        try {
            final RequestParameter[] requestParameters = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
            RequestParameter assertion = null;
            for (RequestParameter rp : requestParameters) {
                if (rp.getKey().equals("assertion")) {
                    assertion = rp;
                }
            }

            if (assertion != null) {
                final String jwtString = assertion.getValue()[0];
                try {
                    final JWT jwt = JWTParser.parse(jwtString);
                    final Object auth = jwt.getJWTClaimsSet().getClaim("auth");
                    if (auth != null) {
                        final JSONArray roles = (JSONArray) ((Map) auth).get("roles");
                        final String[] rolesArray = roles.toArray(new String[0]);
                        LOG.debug("validateScope() rolesArray " + rolesArray);
                        tokReqMsgCtx.setScope(rolesArray);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public boolean issueRefreshToken() throws IdentityOAuth2Exception {
        return false;
    }
}

然后只需编辑repository/conf/identity/identity.xml以引用您的扩展授权处理程序:

        <SupportedGrantType>
            <GrantTypeName>urn:ietf:params:oauth:grant-type:jwt-bearer</GrantTypeName>
            <!--<GrantTypeHandlerImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler</GrantTypeHandlerImplClass>-->
            <GrantTypeHandlerImplClass>xxx.JWTBearerGrantHandlerJWTAuthAware</GrantTypeHandlerImplClass>
            <GrantTypeValidatorImplClass>org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator</GrantTypeValidatorImplClass>
        </SupportedGrantType>