Search code examples
wso2keycloakwso2-api-managerwso2-appm

Retrieve end user information from IdP in a sequence


There is a legacy Rest service which has its own authentication architecture (self-owned db to store user information and using basic auth). Other rest services are all using Keycloak as IdP (with OpenID as token).

I'm trying to use WSO2 API manager before the legacy Rest API that it can authenticate calls using OpenID just as other api services. I found there's a guide saying how to pass the end user attributes to the back-end service and also how to pass a custom authorization token to the back-end service.

And now, I want to know whether it is possible to retrieve the caller's id (viz., the end user id) in a sequence or not? It means I can get the end user's id from a property, modify it and then set it to the Authorization header.

Thus, the complete process seems as:

  1. An end user generates a JWT token from Keycloak
  2. The end user calls an api published by API Manager with the token
  3. API Manager retrieves the end user's userid and sets it into the Authorization header
  4. API Manager calls the back-end service with the changed Authorization header

Solution

  • You can try implementing the following sequence as an in-sequence to your API. The following sequence retrieves the End User ID using the Synapse Properties and assigns it to the Authorization Header.

    <?xml version="1.0" encoding="UTF-8"?><sequence xmlns="http://ws.apache.org/ns/synapse" name="username-header">
        <property name="userid" expression="$ctx:api.ut.userName"/>
        <!-- property name="userid" expression="$ctx:api.ut.userId"/ -->
        <log level="custom">
            <property name="User ID" expression="$ctx:userid" />
        </log>
    
        <property name="Authorization" expression="$ctx:userid" scope="transport" action="set" />
    </sequence>
    

    Furthermore, you can also try using the following Synapse properties, if the above doesn't fulfil your requirement.

    • api.ut.username
    • api.ut.userId

    If you are trying to read the end user's ID from the Backend JWT token that is generated by the API Manager during the API invocation, then it is required to come up with an extended mediation sequence, to read and decode the Token, and then to extract the information. Given below is a sample (not complete) if the requirement is as described above

    <?xml version="1.0" encoding="UTF-8"?>
    <sequence xmlns="http://ws.apache.org/ns/synapse" name="admin--AssertionAPI:v1.0.0--In">
        <property name="assertion" expression="$trp:X-JWT-Assertion" />
        <log level="custom">
            <property name="Assertion" expression="$trp:X-JWT-Assertion" />
        </log>
        <property name="Body" expression="base64Decode(fn:substring-before(fn:substring-after($ctx:assertion, '.'), '.'))" />
        <log level="custom">
            <property name="body" expression="$ctx:Body" />
        </log>
    
        <!-- use script mediator to access required properties -->
        <!-- and set the value as a header -->
    </sequence>