Monday, May 11, 2015

Writing a custom Grant Handler for WSO2 APIM

Here is a how to guide for writing custom grant handler to WSO2 APIM

I have used WSO2 APIM 1.8 for this example

Simply what you have to do is as follows

1) Implement the "org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler" api class in bundle "org.wso2.carbon.identity.oauth" versoin "4.3.2". Maven dependency for this would be




to simplify, instead of implementing the above api class you can extend the "org.wso2.carbon.identity.oauth2.token.handlers.grant.AbstractAuthorizationGrantHandler" class which will be an abstract class implemented on "AuthorizationGrantHandler" api. This class will have the basic implementation we need. So we can simply extend this class, override methods we need, call the super method withing those implementations so that default implementation(which is in abstract class "AbstractAuthorizationGrantHandler") will get called.

Basic method we need to override will be "public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception" method.

Below is a sample implementation of this scenario

public class CustomGrantHandler extends AbstractAuthorizationGrantHandler {    

    public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception {        


        //Things you need to do 
        return true;

    public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
        ScopesIssuer scopesIssuer = new ScopesIssuer();
        return scopesIssuer.setScopes(tokReqMsgCtx);

    public boolean authorizeAccessDelegation(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception {
        //things you need to do
        return true;

Here within the "tokReqMsgCtx" object you will have all the request parameters you need. as a array of "org.wso2.carbon.identity.oauth2.model.RequestParameter" objects.
You can access this object array as follows


2) Implement  "org.apache.amber.oauth2.common.validators.OAuthValidator" api class in bundle "amber" which will be imported via above mentioned "oauth" dependency. Then override required methods.

3) bundle them to a jar file and deploy it into "<APIM_HOME>/repository/components/lib" folder

4) add this custom authenticator to "<APIM_HOME>/repository/conf/identity.xml" file under "<SupportedGrantTypes>" element as follows.

    {your custom grant handler implementation}
    {your custom oauth validator implemention}

sample would be as follows


Restart APIM and you are set. Invoke the token api with your custom request with providing grant type as "custom_grant" and this handler will get invoked. Sample will be as follows

curl -k -d "grant_type=custom_grant" -H "Authorization: Basic YlB5NzZGNmYyRHYzMmJLeXFSaXVnVWJmM1pRYTpueXFWZ3Y0TTRldFdhRV9JS2NFNXBPYmYyVEVh, Content-Type: application/x-www-form-urlencoded" https://localhost:8244/token

There is an important point you have to take into notice. If you are extending "org.wso2.carbon.identity.oauth2.token.handlers.grant.AbstractAuthorizationGrantHandler" class instead of implementing "org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler" api, then make sure you are overriding the method "public boolean authorizeAccessDelegation(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception" and not invoking the super method within the implementation. Reason is, in the "AbstractAuthorizationGrantHandler" abstract class, there is a implementation for above method which validates the grant type against wso2 custom grant types and oauth2 grant types. Since which we write is a custom grant type, it won't be there in the default wso2 implementations. So the validation fails. Overriding the method will resolve that problem as mentioned above.

Another side note if you are going to use IS as keymanager setup.
Then you'll need to have this custom implementation in IS instead of APIM. for that, do the following.(Needs to have IS 5 for this)

1) Create a IS as a keymanager setup as instructed in [1]

2) copy the jar bundle you created with your custom implementations to "<IS_HOME>/repository/components/lib" folder

3) follow the step 4) for the APIM instructions above and change "identity.xml" file inside "<IS_HOME>/repository/conf" folder and add the "SupportedGrantType" as instructed.

Restart the IS and you are set.

Hope this will be some help for the people who struggles trying to write custom grant handlers for APIM or IS

[1] -