<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Athiththan</title>
    <description>The latest articles on DEV Community by Athiththan (@athiththan11).</description>
    <link>https://dev.to/athiththan11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F205315%2F0457439b-8056-49d3-a10b-7cf15a3ed967.jpg</url>
      <title>DEV Community: Athiththan</title>
      <link>https://dev.to/athiththan11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/athiththan11"/>
    <language>en</language>
    <item>
      <title>WSO2 API Manager &amp; Custom Grant Handler</title>
      <dc:creator>Athiththan</dc:creator>
      <pubDate>Sat, 11 Jan 2020 08:23:24 +0000</pubDate>
      <link>https://dev.to/athiththan11/wso2-api-manager-custom-grant-handler-22ec</link>
      <guid>https://dev.to/athiththan11/wso2-api-manager-custom-grant-handler-22ec</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EiDlMhvE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ag1lCxX4lDNdBqgFcD8SNDw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EiDlMhvE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ag1lCxX4lDNdBqgFcD8SNDw.png" alt="WSO2 API Manager &amp;amp; Custom Grant Handler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Greetings Everyone! 👋
&lt;/h4&gt;

&lt;p&gt;In this medium, I will be 🚶 with you all on how to implement a custom Grant Handler for WSO2 Servers, especially for &lt;strong&gt;WSO2 API Manager&lt;/strong&gt; when you are highly in need to introduce your own …&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The demonstrations are presented and guided using &lt;strong&gt;WSO2 API Manager v2.6&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hmmm… alright. But,&lt;/p&gt;

&lt;h4&gt;
  
  
  Am I in need of one??? 🤔
&lt;/h4&gt;

&lt;p&gt;Depends, maybe Yes, probably you are 💁. &lt;br&gt;
Let me tell you a simple story, where a Goe-Location Startup needed to implement a custom grant to fulfill their security concerns and requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BMFvZ-Y3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AbWsw1tr3IgjkCsSLRX1pAA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BMFvZ-Y3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AbWsw1tr3IgjkCsSLRX1pAA.gif" alt="Lion King Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Locus is a Geo-Location 🌏 service startup and it has been using the WSO2 API Manager to manage all of their exposed REST APIs and legacy SOAP services. Due to the increased demand for Geodata and analytics, one day the Locus team gathered to design a new architecture for their certified devices.&lt;/p&gt;

&lt;p&gt;The 👮 platform security team and a group of Architectures 🤓 proposed Locus to isolate their certified devices from all registered devices by introducing a unique pattern for Access tokens 🔑.&lt;/p&gt;

&lt;p&gt;When further breaking-down the features and analyzing the possibilities of implementing customized Tokens (you can refer to &lt;a href="https://medium.com/@athiththan11/customizing-opaque-access-token-generation-58ec7e493405"&gt;Customizing Opaque Access Token Generation&lt;/a&gt;), the devs found out that the WSO2 API Manager has extensions to develop and plug custom grants 🔐  and handlers.&lt;/p&gt;

&lt;p&gt;👏 👏 👏 well-done guys… kudos for the effort and idea.&lt;/p&gt;

&lt;p&gt;They re-engineered their architecture and introduced a custom grant named &lt;code&gt;locus&lt;/code&gt; with the following required fields to fulfill their requirements&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: the unique ID name of the certified device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;location&lt;/strong&gt;: a regional code where the device has permissions and its current accessible location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;key&lt;/strong&gt;: a unique hash key embed to the certified device upon certification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope I made a good story to explain the case… &lt;br&gt;
Let's keep the stories aside and dive into implementations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Lp71UWmAAeJHi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Lp71UWmAAeJHi/giphy.gif" alt="Simba"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🚧 Implementation
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;WSO2 API Manager&lt;/strong&gt;, or more likely to say the WSO2 Carbon platform is built in a way to extend and plug and play with the functions if required.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;On a Personal Note&lt;/strong&gt;&lt;br&gt;
It is always good to think twice before introducing any customizations or extensions to the platform&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So to achieve our needs, We have to extend the implementation of &lt;strong&gt;AbstractAuthorizationGrantHandler&lt;/strong&gt; and push our enhancements to it.&lt;br&gt;
 &lt;br&gt;
Let's start by setting up a Maven project …&lt;br&gt;
Create a new Maven project and the following dependencies in the POM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.wso2.carbon.identity.inbound.auth.oauth2&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;org.wso2.carbon.identity.oauth&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;6.0.53&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you encounter any dependency resolution errors or if you are not able to resolve the dependencies, add the following repositories to fetch 'em&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;wso2-nexus&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.wso2.org/nexus/content/groups/wso2-public/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;releases&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;enabled&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/enabled&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;updatePolicy&amp;gt;&lt;/span&gt;daily&lt;span class="nt"&gt;&amp;lt;/updatePolicy&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;checksumPolicy&amp;gt;&lt;/span&gt;ignore&lt;span class="nt"&gt;&amp;lt;/checksumPolicy&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/releases&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;pluginRepositories&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pluginRepository&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;wso2-nexus&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.wso2.org/nexus/content/groups/wso2-public/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;releases&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;enabled&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/enabled&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;updatePolicy&amp;gt;&lt;/span&gt;daily&lt;span class="nt"&gt;&amp;lt;/updatePolicy&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;checksumPolicy&amp;gt;&lt;/span&gt;ignore&lt;span class="nt"&gt;&amp;lt;/checksumPolicy&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/releases&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/pluginRepository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/pluginRepositories&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With success, let's dive into the implementation of Grant Handlers. Grant Handlers are responsible to validate the Grant type and to issue Access Tokens.&lt;/p&gt;

&lt;p&gt;Since we don't want to do any customizations to our Access Tokens, we will be only overriding the validateGrant() method to validate the inputs.&lt;/p&gt;
&lt;h4&gt;
  
  
  🌏 Locus Grant Handler
&lt;/h4&gt;

&lt;p&gt;I've made it simple 🙌   for you all to save your precious time. You can complete development at the bottom of this story, but if you have time go through it (I've spent my time to write this one 😢)…&lt;/p&gt;

&lt;p&gt;Given below is the complete implementation of the Locus Grant Handler. I've introduced a couple of &lt;code&gt;isValid()&lt;/code&gt; methods to mock the validation and service calls to any defined data sources.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.grant.sample.handler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.grant.sample.utils.LocusGrantConstants&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.commons.logging.Log&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.commons.logging.LogFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.ResponseHeader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.model.RequestParameter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.token.handlers.grant.AbstractAuthorizationGrantHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LocusGrantHandler&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractAuthorizationGrantHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LogFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LocusGrantHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;validateGrant&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OAuthTokenReqMessageContext&lt;/span&gt; &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IdentityOAuth2Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Locus Grant Handler : Starting to validate grant"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;isGrantValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;RequestParameter&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;reqParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOauth2AccessTokenReqDTO&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getRequestParameters&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nameValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;locationValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;keyValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestParameter&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reqParams&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getKey&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;LocusGrantConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LOCUS_NAME_GRANT_PARAM&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;nameValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;LocusGrantConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LOCUS_LOCATION_GRANT_PARAM&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;locationValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;LocusGrantConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LOCUS_KEY_GRANT_PARAM&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;keyValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameValue&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;locationValue&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;keyValue&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;isGrantValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isValidName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameValue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidLocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locationValue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isValidKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyValue&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isGrantValid&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;AuthenticatedUser&lt;/span&gt; &lt;span class="n"&gt;locusUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthenticatedUser&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;locusUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUserName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyValue&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAuthorizedUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locusUser&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setScope&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOauth2AccessTokenReqDTO&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getScope&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;ResponseHeader&lt;/span&gt; &lt;span class="n"&gt;responseHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseHeader&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;responseHeader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LocusGrantError"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;responseHeader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid Credentials"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RESPONSE_HEADERS"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseHeader&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;responseHeader&lt;/span&gt; &lt;span class="o"&gt;});&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDebugEnabled&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Locus Grant Handler : isGrantValid = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;isGrantValid&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;isGrantValid&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValidName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// mocking database call with a sample list&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;validNames&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"locus-10-09874"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;validNames&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"locus-10-01219"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;validNames&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValidLocation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// mocking the database with a sample list&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validLocations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;validLocations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LK-COLOMBO"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;validLocations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LK-KANDY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;validLocations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValidKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// mocking database call with a sample list&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;validKeys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0987654321"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;validKeys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1234567890"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;validKeys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Find the util class implementation from &lt;a href="https://github.com/athiththan11/LocusGrantHandler/blob/master/src/main/java/com/grant/sample/utils/LocusGrantConstants.java"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;A Toll-Free Tip&lt;/strong&gt; 💪&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is required to create and set an &lt;code&gt;AuthenticatedUser&lt;/code&gt; in the success flow to generate an access token and to bind it to that particular user. Otherwise, we'll end up in a broken flow.&lt;/p&gt;

&lt;p&gt;Due to that, I have introduced and configured the key value of the Device to bound the generated access tokens&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's all about the Grant handler …&lt;br&gt;
Now let's configure our API Manager server to support the custom grant&lt;/p&gt;
&lt;h3&gt;
  
  
  WSO2 API Manager Configurations
&lt;/h3&gt;

&lt;p&gt;Before configuring our API Manager pack, we have to build our Maven project. Execute the following command to build the project&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean package
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And copy and place the built JAR artifact inside the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/components/lib&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Now direct to the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/conf/identity&lt;/code&gt; directory and open up the &lt;code&gt;identity.xml&lt;/code&gt; to add and support our &lt;code&gt;locus&lt;/code&gt; grant with API Manager&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SupportedGrantTypes&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="nt"&gt;&amp;lt;SupportedGrantType&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GrantTypeName&amp;gt;&lt;/span&gt;locus&lt;span class="nt"&gt;&amp;lt;/GrantTypeName&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GrantTypeHandlerImplClass&amp;gt;&lt;/span&gt;com.grant.sample.handler.LocusGrantHandler&lt;span class="nt"&gt;&amp;lt;/GrantTypeHandlerImplClass&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;GrantTypeValidatorImplClass&amp;gt;&lt;/span&gt;com.grant.sample.validator.LocusGrantValidator&lt;span class="nt"&gt;&amp;lt;/GrantTypeValidatorImplClass&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IdTokenAllowed&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/IdTokenAllowed&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/SupportedGrantType&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/SupportedGrantTypes&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and that's all … 🎉&lt;/p&gt;
&lt;h4&gt;
  
  
  👏 Voila!!! 🙌
&lt;/h4&gt;

&lt;p&gt;It is time to do an examination&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/CWaKpKNmHinsY/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/CWaKpKNmHinsY/source.gif" alt="it is time"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Examine 🕵
&lt;/h3&gt;

&lt;p&gt;Fire up the WSO2 API Manager server, and execute the request using either cURL or Postman or from your favorite REST client and take a note ✅&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'https://localhost:8243/token'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: Basic {base64&amp;lt;ClientID:Client Secret&amp;gt;}'&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/x-www-form-urlencoded'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'grant_type=locus'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'name=locus-10-09874'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'location=LK-COLOMBO'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'key=0987654321'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/athiththan11"&gt;
        athiththan11
      &lt;/a&gt; / &lt;a href="https://github.com/athiththan11/LocusGrantHandler"&gt;
        LocusGrantHandler
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Custom Grant (Handler &amp;amp; Validator) Implementation for WSO2 API Manager
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Locus Grant Handler&lt;/h1&gt;
&lt;p&gt;A custom &lt;code&gt;Grant Handler&lt;/code&gt; &amp;amp; &lt;code&gt;Grant Validator&lt;/code&gt; implementation for &lt;code&gt;WSO2 API Manager&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
Implementation &amp;amp; Usage&lt;/h2&gt;
&lt;p&gt;The developed custom grant expects the following to authenticate and generate access tokens&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;name: a unique name&lt;/li&gt;
&lt;li&gt;location: supported location&lt;/li&gt;
&lt;li&gt;key: a unique key value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given below are a set of sample values&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;name: &lt;code&gt;locus-10-09874&lt;/code&gt;, &lt;code&gt;ocus-10-01219&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;location: &lt;code&gt;LK-COLOMBO&lt;/code&gt;, &lt;code&gt;LK-KANDY&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;key: &lt;code&gt;0987654321&lt;/code&gt;, &lt;code&gt;1234567890&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
Configuring &amp;amp; Deploying&lt;/h3&gt;
&lt;p&gt;Use the following command to build the project&lt;/p&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;mvn clean package&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Copy and place the built JAR artifact inside the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/components/lib&lt;/code&gt; directory. Then navigate and open the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/conf/identity/identity.xml&lt;/code&gt; and add the our custom grant under the &lt;code&gt;&amp;lt;SupportedGrantTypes&amp;gt;&lt;/code&gt; section as follows&lt;/p&gt;
&lt;div class="highlight highlight-text-xml"&gt;&lt;pre&gt;&amp;lt;&lt;span class="pl-ent"&gt;SupportedGrantTypes&lt;/span&gt;&amp;amp;gt
    &amp;lt;&lt;span class="pl-ent"&gt;SupportedGrantType&lt;/span&gt;&amp;amp;gt
        &amp;lt;&lt;span class="pl-ent"&gt;GrantTypeName&lt;/span&gt;&amp;gt;locus&amp;lt;/&lt;span class="pl-ent"&gt;GrantTypeName&lt;/span&gt;&amp;amp;gt
        &amp;lt;&lt;span class="pl-ent"&gt;GrantTypeHandlerImplClass&lt;/span&gt;&amp;gt;com.grant.sample.handler.LocusGrantHandler&amp;lt;/&lt;span class="pl-ent"&gt;GrantTypeHandlerImplClass&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span class="pl-ent"&gt;GrantTypeValidatorImplClass&lt;/span&gt;&amp;gt;com.grant.sample.validator.LocusGrantValidator&amp;lt;/&lt;span class="pl-ent"&gt;GrantTypeValidatorImplClass&lt;/span&gt;&amp;gt;
        &amp;lt;&lt;span class="pl-ent"&gt;IdTokenAllowed&lt;/span&gt;&amp;gt;false&amp;lt;/&lt;span class="pl-ent"&gt;IdTokenAllowed&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span class="pl-ent"&gt;SupportedGrantType&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span class="pl-ent"&gt;SupportedGrantTypes&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
Test Case&lt;/h3&gt;
&lt;p&gt;Fire up the &lt;code&gt;WSO2 API Manager&lt;/code&gt; server by navigating to…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/athiththan11/LocusGrantHandler"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>wso2</category>
      <category>wso2apimanager</category>
      <category>granthandler</category>
    </item>
    <item>
      <title>Customizing Opaque Access Token Generation</title>
      <dc:creator>Athiththan</dc:creator>
      <pubDate>Sun, 05 Jan 2020 13:04:55 +0000</pubDate>
      <link>https://dev.to/athiththan11/customizing-opaque-access-token-generation-1ib2</link>
      <guid>https://dev.to/athiththan11/customizing-opaque-access-token-generation-1ib2</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Hola 👋&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Greetings&lt;/strong&gt; Everyone 😊 …&lt;br&gt;
This is another medium on walking 🚶 and swimming 🏊🏼 through customizing the opaque access tokens using APIM Token Issuer when we do have a requirement issue&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The demo is presented and walked-through using WSO2 API Manager v2.6&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;Whaaaaat? wait… Why? 🤔&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;You probably now have a question on why do we need to do that and does it actually matter… Let me give you a simple stupid occasion on when and where I actually need that.&lt;/p&gt;

&lt;p&gt;RepoDeWS is a developer-management system which has a set of in-built management services in SOAP. These SOAP services are exposed as REST APIs with the help of WSO2 API Manager. Now the RepoDeWS team is having an undergoing process of security maintenance and they are expecting their users to invoke the APIs using access tokens with a "&lt;strong&gt;Dev-Hash&lt;/strong&gt;" value appended to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This "Dev-Hash" value will be passed as a Header (devhash) when requesting an Access Token and will be appended during the generation of the opaque access token&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh… I forgot to mention that the &lt;strong&gt;Dev-Hash&lt;/strong&gt; value is a unique hash value given to a set of top-rated developers to enrich their API responses with the last accessed timestamps 😅&lt;/p&gt;

&lt;p&gt;Let's just focus on the implementation and enhancements and will keep our use-cases behind that.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Implementation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To accomplish my simple requirement, We have to extend the implementation of &lt;strong&gt;APIMTokenIssuer&lt;/strong&gt; and push our enhancements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;APIMTokenIssuer&lt;/strong&gt; is responsible for generating opaque access tokens and JWT tokens in the WSO2 API Manager platform&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, create a simple maven project and add the following dependency to the POM. This will help us to resolve most of the dependency issues when extending the APIMTokenIssuer class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.wso2.carbon.apimgt&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;org.wso2.carbon.apimgt.keymgt&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;6.5.222&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But, if you encounter any dependency problems or if you are not able to resolve the dependencies in the POM, then add the following as well …&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;wso2-nexus&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.wso2.org/nexus/content/groups/wso2-public/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;releases&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;enabled&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/enabled&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;updatePolicy&amp;gt;&lt;/span&gt;daily&lt;span class="nt"&gt;&amp;lt;/updatePolicy&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;checksumPolicy&amp;gt;&lt;/span&gt;ignore&lt;span class="nt"&gt;&amp;lt;/checksumPolicy&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/releases&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;pluginRepositories&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;pluginRepository&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;wso2-nexus&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://maven.wso2.org/nexus/content/groups/wso2-public/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;releases&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;enabled&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/enabled&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;updatePolicy&amp;gt;&lt;/span&gt;daily&lt;span class="nt"&gt;&amp;lt;/updatePolicy&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;checksumPolicy&amp;gt;&lt;/span&gt;ignore&lt;span class="nt"&gt;&amp;lt;/checksumPolicy&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/releases&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/pluginRepository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/pluginRepositories&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Phew&lt;/strong&gt; 😅&lt;br&gt;
Managing dependencies is harder than managing expenses bruh 😬😬😭 …&lt;/p&gt;

&lt;p&gt;Now let's jump into the extended implementation. Given below is the piece of code (I) developed to solve my own problem [Am I overreacting 😳 ? I think I am 😒]&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.sample.token&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.apimgt.impl.APIConstants&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.apimgt.impl.utils.APIUtil&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.apimgt.keymgt.issuers.APIMTokenIssuer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.wso2.carbon.identity.oauth2.model.RequestParameter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyAPIMTokenIssuer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;APIMTokenIssuer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoggerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLog&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyAPIMTokenIssuer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OAuthTokenReqMessageContext&lt;/span&gt; &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;OAuthSystemException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// generate access token using super method&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOauth2AccessTokenReqDTO&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getClientId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;APIUtil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getApplicationByClientId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;tokenType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTokenType&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="c1"&gt;// only acceptable for opaque access tokens and not JWT tokens&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="nc"&gt;APIConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;JWT&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenType&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// retrieve all request parameters sent to the token request&lt;/span&gt;
        &lt;span class="nc"&gt;RequestParameter&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;reqParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokReqMsgCtx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOauth2AccessTokenreqDTO&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getRequestParameters&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;reqParams&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// check for devhash from the request parameters &lt;/span&gt;
          &lt;span class="c1"&gt;// and append it to the access token&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"devhash"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reqParams&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;getKey&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;reqParams&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APIManagementException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Exception occured "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;accessToken&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I know right, it’s really hard to follow these things up 😐&lt;br&gt;
Therefore, I give you a golden opportunity… Please go and find the sample implementation (gist) from &lt;a href="https://gist.github.com/athiththan11/905f0c875c619630327cd869ca1b01f9"&gt;GitHub Gist&lt;/a&gt; (save your time on reading this medium) and enjoy enriching it 😍&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Your inner voice:&lt;/strong&gt; Hmmm… Thanks for that. I have gone through the samples and copied everything from the given sources. Now, what should I do next? Where should I put these implementations???&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Ummm… I think I heard your inner voice. But thank you for the question.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--70yldEjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/500/1%2ARQ1nQUxFwVA9Hn__BNlcRA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--70yldEjq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://miro.medium.com/max/500/1%2ARQ1nQUxFwVA9Hn__BNlcRA.gif" alt="May the Force be with us all"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of next steps we have to build-up the maven project by executing the following command from a terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean package
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And then copy and place the built JAR artifact from the &lt;code&gt;target&lt;/code&gt; folder to the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/components/lib&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;And at last [Whoa…. the magical keyword 🤗😍], change the APIMTokenIssuer class representation to the &lt;code&gt;MyAPIMTokenIssuer&lt;/code&gt; class by editing the &lt;code&gt;&amp;lt;IdentityOAuthTokenGenerator&amp;gt;&lt;/code&gt; property in the &lt;code&gt;&amp;lt;APIM&amp;gt;/repository/conf/identity/identity.xml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;IdentityOAuthTokenGenerator&amp;gt;&lt;/span&gt;com.sample.token.MyAPIMTokenIssuer&lt;span class="nt"&gt;&amp;lt;/IdentityOAuthTokenGenerator&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fvWjAXGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1920/1%2Az63e3YMOK2d6cuXHLODBJA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fvWjAXGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1920/1%2Az63e3YMOK2d6cuXHLODBJA.png" alt="identity.xml"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;🎉 Voila!!! 🎉&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Let’s do a test-run with our piece of code…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep Stacking!!!&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Test Drive&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Fire up the &lt;strong&gt;WSO2 API Manager&lt;/strong&gt; server with the artifacts and the above-mentioned configuration changes.&lt;/p&gt;

&lt;p&gt;Execute the following CURL command to generate an Opaque Access Token and let’s verify whether it got generated with the specified &lt;strong&gt;Dev-Hash&lt;/strong&gt; value or not…&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="s1"&gt;'https://localhost:8243/token'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/x-www-form-urlencoded'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: Basic {Base64&amp;lt;ClientID&amp;gt;:&amp;lt;ClientSecret&amp;gt;} \
--data-urlencode '&lt;/span&gt;&lt;span class="nv"&gt;grant_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password&lt;span class="s1"&gt;' \
--data-urlencode '&lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin&lt;span class="s1"&gt;' \
--data-urlencode '&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin&lt;span class="s1"&gt;' \
--data-urlencode '&lt;/span&gt;&lt;span class="nv"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;default&lt;span class="s1"&gt;' \
--data-urlencode '&lt;/span&gt;&lt;span class="nv"&gt;devhash&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;af1c4ca13ab7d6c8d2a887d7ce8250a2&lt;span class="s1"&gt;'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And the response should be as follows with the &lt;strong&gt;Dev-Hash&lt;/strong&gt; value appended to the Access Token&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"access_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"25b9ded7-7441-3b69-bb6b-b1f1828bfff9af1c4ca13ab7d6c8d2a887d7ce8250a2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"refresh_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"d86ac9b8-a3aa-3664-9d39-090ca49a9435"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/athiththan11"&gt;
        athiththan11
      &lt;/a&gt; / &lt;a href="https://github.com/athiththan11/Sample-APIMTokenIssuer"&gt;
        Sample-APIMTokenIssuer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple custom APIM Token Issuer Implementation
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Custom APIM Token Issuer&lt;/h1&gt;
&lt;p&gt;A sample extended &lt;code&gt;APIMTokenIssuer&lt;/code&gt; implementation to append a custom value to the generated Opaque Access Tokens.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://medium.com/@athiththan11/customizing-opaque-access-token-generation-58ec7e493405" rel="nofollow"&gt;A Medium Blog: Customizing Opaque Access Token Generation&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Implementation&lt;/h2&gt;
&lt;p&gt;This is a sample implementation to demonstrate on how-to extract a custom header sent to with the &lt;code&gt;Token&lt;/code&gt; request and append it to the generate Opaque access token.&lt;/p&gt;
&lt;p&gt;The custom header used here is called as &lt;code&gt;devhash&lt;/code&gt; which is a hash value as &lt;code&gt;data-urlencode&lt;/code&gt; with the &lt;code&gt;Token&lt;/code&gt; request.&lt;/p&gt;
&lt;p&gt;Given below is a sample &lt;code&gt;/token&lt;/code&gt; requst&lt;/p&gt;
&lt;div class="highlight highlight-source-httpspec"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;POST&lt;/span&gt; https://localhost:&lt;span class="pl-c1"&gt;8243&lt;/span&gt;/token
&lt;span class="pl-s"&gt;&lt;span class="pl-v"&gt;Authorization:&lt;/span&gt; Basic &amp;lt;Base64 {Client ID}:{Client Secret}&amp;gt;&lt;/span&gt;
&lt;span class="pl-s"&gt;&lt;span class="pl-v"&gt;Content-Type:&lt;/span&gt; application/x-www-form-urlencoded&lt;/span&gt;
grant_type&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;password&lt;/span&gt;
username&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;admin&lt;/span&gt;
password&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;admin&lt;/span&gt;
scope&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;defualt&lt;/span&gt;
devhash&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;af1c4ca13ab7d6c8d2a887d7ce8250a2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;curl --location --request POST 'https://localhost:8243/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --header 'Authorization: Basic &amp;lt;Base64 {Client ID}:{Client Secret}&amp;gt; \
    --data-urlencode 'grant_type=password' \
    --data-urlencode 'username=admin' \
    --data-urlencode 'password=admin' \
    --data-urlencode 'scope=default' \
    --data-urlencode 'devhash=af1c4ca13ab7d6c8d2a887d7ce8250a2'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the response should be as follows...&lt;/p&gt;
&lt;div class="highlight highlight-source-json"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/athiththan11/Sample-APIMTokenIssuer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>wso2</category>
      <category>wso2apimanager</category>
      <category>apimtokenissuer</category>
      <category>accesstoken</category>
    </item>
  </channel>
</rss>
