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
org.wso2.carbon.identity
org.wso2.carbon.identity.oauth
4.3.2
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 {
@Override
public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
throws IdentityOAuth2Exception {
super.validateGrant(tokReqMsgCtx);
//Things you need to do
return true;
}
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
ScopesIssuer scopesIssuer = new ScopesIssuer();
return scopesIssuer.setScopes(tokReqMsgCtx);
}
@Override
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
tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
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.
{grant_type_name}
{your custom grant handler implementation}
{your custom oauth validator implemention}
sample would be as follows
custom_grant
com.custom.grant.handler.handlers.CustomGrantHandler
com.custom.grant.handler.handlers.CustomValidator
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] - https://docs.wso2.com/display/CLUSTER420/Configuring+WSO2+Identity+Server+as+the+Key+Manager