Skip to Content
Technical Articles

Part 1 : Modeling the JWT token verification flows in SAP Cloud Platform API Management

The JWT policies of SAP Cloud Platform API Management enables you to generate, verify and decode the JWT token.  In the Blog Series : JSON Web Tokens (JWT) verification using SAP Cloud Platform API Management we have covered the modeling and configuration of JWT verification  policies for various Identity providers like SAP Cloud Platform XS UAAOkta , Azure Active Directory . In this part of the blog series, we have covered the steps for Modeling the JWT token verification policy using SAP Cloud Platform API Management.

For the verification of JWT token, you will need the public key that is associated with the private key which was used to sign your JWT token. This public key can be passed as the value field in JWT token policy or alternatively you can use a JSON representation of your public keys in JSON Web Keys ( JWKS) format. A sample JWKS response is provided in here.  Most of the Identity Providers provide an endpoint or service URL for their JWKS. At a high level, a simple JWT token verification policies would consist of the following steps :-

  • Reading of JWKS response from your Identity Providers.
  • Caching JWKS response to be used in subsequent calls.
  • Verification of JWT token with JWKS response input for public keys.

Note :- To keep the blog short, the policy modeling part is covered in this blog. Steps to create an API Proxy is covered in this tutorial.

  • Navigate to your SAP Cloud Platform API Management service from SAP Cloud Platform cockpit -> Services tab.
  • Access your API Portal service.
  • Navigate to Develop tab and select the API Proxy that you will like to protect using JWT and apply JWT token verification policies.

  • From the selected API Proxy details view, click Policies to open Policy Designer

  • Click Edit on the policy designer, to enter edit mode.

  • The policies for JWT verification would be applied to the incoming request from client application and should be enforced for all incoming calls. First, the JWKS response from SAP Cloud Platform API Management cache would be read and for reading cache you can use a Lookup cache policy.
  • Select ProxyEndPoint->PreFlow , select + button next to the Look up cache policyavailable under section Traffic Management Policies.

 

  • In the Create Policy dialog, enter a name for your policy say readCachedKeys and click Add. The name of the Lookup cache policy that you provide needs to be noted as you will be using this name in subsequent steps, like to check if the JWKS response was missing in local cache ( for the first time calls before the JWKS response is cached).

 

  • Select the newly added policy named readCachedKeys and provide the following policy snippet. In this snippet, JWKS response from a cache key named JWT_KEYS is read and this cached response is assigned to a local flow variable named JWTKeys.content. The scope is set to Global, so that JWKS cache response can be reused across multiple API Proxies.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LookupCache async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
    <CacheKey>
        <KeyFragment>JWT_KEYS</KeyFragment>
    </CacheKey>
    <Scope>Global</Scope>
    <AssignTo>JWTKeys.content</AssignTo>
</LookupCache>

 

 

  • In case, the Lookup cache policy fails like the first time the API Proxy is called there is no cached JWKS response in SAP Cloud Platform API Management, you can use a Service callout policy to call the JWKS endpoint of your Identity Provider system.
  • Select + button next to the Service Callout available under section Extension Policies.

  • In the Create Policy dialog, enter a name for your policy say readJWKS and then click on Add. 

  • You need to execute this policy only in scenario where reading of the JWKS response from SAP Cloud Platform API Management cache fails. You can use the following condition snippet to specify the conditions to check if Lookup cache policy was successful or not. In the snippet below readCachedKeys is name of the Lookup cache policy.
 lookupcache.readCachedKeys.cachehit = false
  • Select the newly added policy named readJWKS and provide the above condition snippet in the Condition String text box.

 

  • Provide the following ServiceCallout policy snippet to invoke the JWKS endpoint of your Identity Provider and set the response to flow variable named JWTKeys. Note, based on your selected Identity Provider the JWKS endpoint would vary and URLproperty of the policy snippet would have to adjusted accordingly.
<ServiceCallout async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
	<Response>JWTKeys</Response>
	<Timeout>30000</Timeout>
	<HTTPTargetConnection>
		<URL>https://your_identity_provider_jwks_url/</URL>
 	</HTTPTargetConnection>
</ServiceCallout>

  • In case, the Lookup cache policy fails or expires and the JWKS response fetched from the Identity provider would have to be on SAP Cloud Platform API Management so that it can be used in subsequent API Proxy invocations. You can use the Populate cache policy from SAP Cloud Platform API Management to cache the JWKS response.
  • Select + button next to the Populate cache policy available under section Traffic Management Policies.

 

  • In the Create Policy dialog, enter a name for your policy say cacheJWKS and then click on Add. 

 

  • As before, you need to execute this policy only in scenario where reading of the JWKS response from SAP Cloud Platform API Management cache fails. You can use the following condition snippet to specify the conditions to check if Lookup cache policy was successful or not. In the snippet below readCachedKeys is name of the Lookup cache policy.
 lookupcache.readCachedKeys.cachehit = false
  • Select the newly added policy named cacheJWKS and provide the above condition snippet in the Condition String text box.

  • Provide the following Populate cache policy snippet to cache the content of your Service callout response content ( JWTKeys.content) in cache key named JWT_KEYS. The scope of the Populate cache policy snippet is set to Global so that it can used across multiple API Proxies and the cache expiration interval is set to one day. You can adjust the cache expiration interval based on your requirement.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PopulateCache async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
    <CacheKey>
        <KeyFragment>JWT_KEYS</KeyFragment>
    </CacheKey>
    <Scope>Global</Scope>
    <ExpirySettings>
        <TimeoutInSec>86400</TimeoutInSec>
    </ExpirySettings>
    <Source>JWTKeys.content</Source>
</PopulateCache>

 

  • Finally, you can use the verify JWT policy to verify the incoming JWT token in your incoming request to the API Proxy.  Select + button next to the Verify JWT policyavailable under section Security Policies.

Disclaimer :- JWT policies from SAP Cloud Platform API Management is not yet available in trial environment, so in your trial environment the Verify JWT policy won’t be visible.

  • In the Create Policy dialog, enter a name for your policy say verifyJWT and then click on Add. 

 

  • Select the newly created veriyJWT policy and provide the following VerifyJWT policy snippet to verify the JWT token which is signed using RS256 algorithm. In case of RS256 algorithm, you will need to specify the Public key used for the signing of the JWT token. You can use the JWKS element of the PublicKey element to provide a  reference to the flow variable JWTKeys.content which contains the JWKS response from your identity provider.
  • You can add in the issuer of your JWT token and during the validation of JWT token the issuer in the incoming token would be matched against the issuer specified in the policy. In case of mismatch in the issuer it will raise a unauthenticated error ( HTTP status code 401).  The JWT token in the incoming request would be read from authorization header ( HTTP header named authorization) in the format Bearer {access_token_in_jwt_format}.

Note:- You can use the Source element of VerifyJWT token policy to provide the source of your JWT token. If Source is not present, VerifyJWT token policy will read the JWT token from the HTTP header named authorization.

<!-- Verify JWT TOken -->
<VerifyJWT async="false" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
    <Algorithm>RS256</Algorithm>
     <PublicKey>
    		<JWKS ref="JWTKeys.content"/>
    </PublicKey>
    <Issuer>your_jwt_token_issuer</Issuer>
</VerifyJWT>

 

  • Select Update to persist all the policy changes

 

  • Click Save to persist all the API Proxy changes.

 

The JWKS URL and the issuer for JWT token verification would vary based on your chosen Identity Provider. To configure the policies based on your chosen Identity provider refer the Blog Series : JSON Web Tokens (JWT) verification using SAP Cloud Platform API Management.

11 Comments
You must be Logged on to comment or reply to a post.
  • Hi Mattias,

    Thanks a lot for your kind words.

    You would be able to store the public key in the key value map instead of the key store. This key value map can be read using the key value map policy and later used within the VerifyJWT token policy.

    Thanks and Best Regards,

    Divya

  • Divya, thank you for this blog.  It has been helpful.  In my instance of SAP APIM.  I don’t see any option for verifyJWT.  Am I missing something?

     

    /
  • Hi Mark,

    Hopefully you are now able to see the JWT token policies . In case you continue to face the issue on your productive accounts, kindly raise a customer incident on the API Management component OPU-API-OD-OPS so that our DevOps team can assist you .

    Thanks,

    Divya

  • Hi Divya and SAP Community,

     

    Thanks in advance for this blog. I’ve been following this blog to a creation of an API using JWT and XSUAA information to connect to a certain endpoint.

    After following you part 1 and 4, i ran my service on the API Test Console in Debug mode, and i found that i have an error with status 500 in the response.

    According to the Debug feature, the error is on the verifyJWT Policy, i used your code snipet and used the my issuer url as you told in Part 4.

    Appart of the status code, the response retrieved is :

    {
    “fault”:{
    “faultstring”:“Invalid token: policy(java.lang.NullPointerException)”,
    “detail”:{
    “errorcode”:“steps.jwt.InvalidToken”
    }
    }
    }

     

    • Have you gone through this error on your implementations?
    • If so, did you do any workaround that you wouldn’t mind share?

     

    I’ve also run this on postman, passing the Bearer token in the “Authorization tab”, i get status code 200 but it comes without any response when it should because if i run the service without using the API, the response comes finelly. Do you know the reason for that difference in both responses from Postman and API Test Console?

     

    Thanks in advance,

    Best Regards,

    Francisco Ferreira.

    • Hi Francisco,

      The null pointer exception would mean that it API Proxy is not finding the OAuth access token . While testing the API Test Console, hope you are passing the OAuth token by clicking on the Headers tab and then setting the header name as Authorization and Header value as Bearer {access_token} format.

      For the status code 200, when being called from Postman, can you check if the call is reaching successfully your API ?

      Thanks,

      Divya

      • Hi Divya,

         

        Thank you for the response.

        When calling by Postman, it is reaching the API successfully, because in the API Debug Viewer for the API created, all the policies appear as green. I think the request might be getting stuck on the Identity provider of the application. I’m trying to see a workaround on that, like generating the bearer on a policy.

         

        Thank you for your attention,

        Best Regards,

        Francisco Ferreira