Wednesday, July 8, 2015

Enable CORS WSO2 Data services server

This post is about how to enable CORS in Wso2 Data Services server.

I'll explain in point form as it will be easy for readers to understand and test the scenario. (I have tested this in DSS 3.2.2 version)

1) downloaded "cors-filter-2.4.jar" and "java-property-utils-1.9.1.jar" from the site [1] and added those jars to DSS/repository/components/lib folder

2) added below config elements to DSS/repository/conf/tomcat/web.xml file
   
  CORS
  com.thetransactioncompany.cors.CORSFilter  
 


        CORS
        /*

3) restarted the DSS and then CORS will work fine now

PS - you can fine tune url pattern to allow this to limited url patterns. for example you can use pattern as below
/services/*
using this you can fine tune it to allow CORS for only some of the services hosted in DSS

[1] - http://software.dzhuvinov.com/cors-filter-installation.html

Hope this helps :-)

Wednesday, June 17, 2015

Use Intellij IDEA to make your debugging life easy

Here is a simple tip which will make it easy to debug codes and try out new things in Intellij IDEA

First thing is we can use Intellij IDEA to remote debug codes which runs in servers. But this post is not about configuring remote debugging in Intellij IDEA.

Lets take an example - We use WSO2 server, say WSO2-AS. We are remote debugging an application we deployed in AS for a issue with IDEA. Say we find the solution. Normal procedure is to implement the solution, build it, and redeploy it. But this may take considerable amount of time. But using Intellij Idea, we can reduce this burden. What we have to do is attach IDEA remote debugger to AS, implement the required code and then compile that code within IDEA. After compiling the code IDEA will automatically reloads the attached JVM's class instance with newly compiled code.

This makes life easy, as we don't need to rebuild and redeploy codes to apply the changes.

Bellow are the steps listed down again for clarity

1) Attach IDEA remote debugger to the server
2) Do the required code change in the source
3) Compile the code within IDEA (You can do this by right clicking on the class and select "compile")

And that's it, IDEA will reload the attached JVM with newly changed class.

Notes -
1) We can't use this method to reload big changes done on the source. Say like implementing new class, adding new dependency etc
2) This method will be very much useful in scenarios where we even have to restart the servers to apply changes. Say debugging component issues in wso2 products.
3) This reload only affects current running JVM instance. If we restart the server, these changes will be gone as server will reload original classes from bundles

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



            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