2
votes

This is the final piece I need to wrap up this integration:

  • I have an external Identity Provider that generates JWT tokens. These tokens contain a claim "auth" that includes the permissions of a user, e.g: "auth" : [ "editor", "reviewer"].

  • In WSO2 I have an API that requires the "editor" scope in some of its endpoints:

  • I am using JWT Grant to exchange the JWT from the external IP for a WSO2 access token to invoke the API.

I need that when WSO2 creates the access token it associates it with the scopes contained in the "auth" claim from the JWT.

Is this possible? Is there an extension point where this could be implemented?

2

2 Answers

1
votes

This is how I finally solved it extending 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;
    }
}

Then just edit repository/conf/identity/identity.xml to reference your extended grant handler:

        <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>
1
votes

This should be possible by extending JWT grant type and overriding validateScope method. You can retrieve the scopes from JWT and set it to tokReqMsgCtx. Then you should be able to setScopes like bellow.

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

For example, have a look at how this is done for SAML2 bearer grant type [1].

If you are using the JWT grant type it is configured inside SupportedGrantTypes section of "repository/conf/identity/identity.xml" file. Related GrantTypeHandlerImplClass is mentioned within the configuration.

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

Refer to document[2] on writing custom grant type.

[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