Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

When proxying calls to your back end API, the API Manager adds a header with details gathered during the authentication process.  These details are commonly used for:

  • Fine grained access decisions - e.g. "Users can only access class details for classes they are enrolled in"
  • Auditing - e.g. "The class was deleted by XXX"
  • Returning "Your" data - e.g. "Invoking the api will return the current user's calendar"

When a client invokes your API, all of the headers, query parameters and content will be passed along to your backend API, untouched.  There are two exceptions to this rule.  First the Authorization header submitted by the client is used by the APIM to determine access and is stripped from the request before it's passed to the backend.  Secondly a digitally signed JSON Web Token (JWT) is added as a header.  This JWT contains

  • information about the entities involved.  This includes
    • Which Application made the call
    • Which user is currently sitting behind the key board (if available).
    • A Signature to verify that the JWT is from the API Manager
    • Security details to prevent replay and similar attacks.
  • information about the authentication preformed (e.g.  did the user or just application authenticate).

Resources:

The above resources have thorough explanations of what a JWT is how to use it, so this page will focus on the specific UCSD implementation.

The Header

The JWT will look like this:

X-JWT-Assertion: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5XVTJaV1F3WlRsbU1EVTVNbUpqWWpBd05tUTNOVFUyT1dFek5EQXlZakEyWm1NMFlqUm1OQT09In0=.eyJpc3MiOiJ3c28yLm9yZy9wcm9kdWN0cy9hbSIsImV4cCI6MTQ3OTQxMDU1MTY4MSwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9zdWJzY3JpYmVyIjoibHplbHVzIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9hcHBsaWNhdGlvbmlkIjoiMSIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvYXBwbGljYXRpb25uYW1lIjoiRGVmYXVsdEFwcGxpY2F0aW9uIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9hcHBsaWNhdGlvbnRpZXIiOiJVbmxpbWl0ZWQiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL2FwaWNvbnRleHQiOiIvZWNoby8xLjAuMCIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvdmVyc2lvbiI6IjEuMC4wIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy90aWVyIjoiVW5saW1pdGVkIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9rZXl0eXBlIjoiUFJPRFVDVElPTiIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvdXNlcnR5cGUiOiJBUFBMSUNBVElPTiIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvZW5kdXNlciI6Imx6ZWx1c0BjYXJib24uc3VwZXIiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL2VuZHVzZXJUZW5hbnRJZCI6Ii0xMjM0IiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9hZHVzZXJuYW1lIjoiLSIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvZGVwYXJ0bWVudGNvZGVzIjoiMDAwNDQ0LDAwMDQyNSIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvZWlkIjoiOTI3MTI0IiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9lbWFpbGFkZHJlc3MiOiJsemVsdXNAdWNzZC5lZHUiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL2dpdmVubmFtZSI6IkxvdWlzIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9sYXN0bmFtZSI6IlplbHVzIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9uZXR3b3JrdXNlcmlkIjoibHplbHVzIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9uaWNrbmFtZSI6Imx6ZWx1cyIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvcGFzc3dvcmRUaW1lc3RhbXAiOiJsemVsdXMiLCJodHRwOi8vd3NvMi5vcmcvY2xhaW1zL3BpZCI6IkExMjUwMzMyOSIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvcmFjZmlkIjoiREVWTERaIiwiaHR0cDovL3dzbzIub3JnL2NsYWltcy9yb2xlIjoiSW50ZXJuYWwvbHplbHVzX0RlZmF1bHRBcHBsaWNhdGlvbl9QUk9EVUNUSU9OLEludGVybmFsL2x6ZWx1c19EZWZhdWx0QXBwbGljYXRpb25fU0FOREJPWCxJbnRlcm5hbC9semVsdXNfTG91aXNUZXN0QXBwX1BST0RVQ1RJT04sSW50ZXJuYWwvbHplbHVzX1J1bnNjb3BlVGVzdEFwcF9QUk9EVUNUSU9OLEludGVybmFsL2x6ZWx1c19SdW5zY29wZVRlc3RBcHBfU0FOREJPWCxJbnRlcm5hbC9semVsdXNfRVNCX0UyVF9QUk9EVUNUSU9OLEludGVybmFsL2x6ZWx1c19BUElNVG9rZW5MaWJUZXN0X1BST0RVQ1RJT04sSW50ZXJuYWwvbHplbHVzX0FQSU1Ub2tlbkxpYlRlc3RfU0FOREJPWCxJbnRlcm5hbC9semVsdXNfRGV2bG9wZXJzTW9udGhseURlbW9fUFJPRFVDVElPTixJbnRlcm5hbC9semVsdXNfRGV2bG9wZXJzTW9udGhseURlbW9fU0FOREJPWCxJbnRlcm5hbC9ldmVyeW9uZSIsImh0dHA6Ly93c28yLm9yZy9jbGFpbXMvc3lzdGVtaWQiOiIwNDZmMzRlNzRkYzEyNDc1MDE0ZWZiMzFlZWYwMGUzNiJ9.IgICZeaUYLvTUkOLK+KxbDNf15eC/pO8w7jLvS1vsKMssMiIKwUD99QZMhP6P1fqblA5j34HM7l5z/gocKSX+snHvKQAara4oWTgpSUpf+SVzOqIFqn1d6Bg1pcXgULsiYploL5fbU/LC1rrT7Hdg05rKNHpvH06V6t7fBrMpvNLtGOLcV0FDsU1XPpJh8YLy6XFL01Jhkbw5L0N1ecHoq3QXq8St279eirQspbFjzz/tbUIEOgCCgI9hWoVjR9Y1pUfn5ARqEBLSqVdX8cAfdbNDJVtYAPm96q94zpJA8Yg6A3mVeMWZ5xSJpHSNN4C3ew97HHWGrbOMuPrF2mfBg==

See the above resources for a description of what the different parts mean, https://scotch.io/tutorials/the-anatomy-of-a-json-web-token is a particularly good place to start.

This header is only on the request sent to the backend. It is not added to the response sent to the client. This often causes some confusion to people new to JWT as they hope to inspect the header in their browser or similar client. To see the JWT header you must log, store, print or return it from a web service that is invoked by the APIM. See the section below about the Echo API which does just that. 

The Echo API

UCSD has implemented an API specifically for testing and demonstration.  This API simply returns everything passed to it.  Additionally it is specifically designed to also return the JWT that it received.  This means that you can use a web client (like Postman) to invoke the echo API and inspect the JWT in the response.

The JWT should not be returned to the client, it is intended for the backend API's use. The JWT features of the Echo API and the APIM Javascript Tester are non-standard and discouraged usages of the JWT. These tools purposely break this convention to make it easier for API developers to "see" an example of a JWT. While this is helpful when learning about JWT's, it should not be emulated in production code.

APIM Javascript Tester

A pure javascript API client is avialiable at https://lzelus.github.io/APIM/APIMJavascriptTester.html.  It has a special feature when used to invoke the Echo API.  It will detect the returned JWT and decode it, rendering the data that it received. 

To use it,

  1. Got to the Application page of the APIM Manager (https://api-qa.ucsd.edu/store/site/pages/applications.jag).
  2. Create a new application:
    1. Name: XXX's APIM Javascript Tester
    2. Callback URL: https://lzelus.github.io/APIM/APIMJavascriptTester.html
  3. Subscribe this new Application to the Echo API.
  4. Copy the "Client Key" from your subscriptions page (be sure that your new application is selected).  
  5. Open the APIM Javascript Tester and paste your Client Key.  
  6. Click "Request an OAuth access token".  
  7. This will send you to UCSD's SSO unless you already have an active SSO session.  Login using your Business Systems account.
  8. You should be returned to the APIM Javascript Tester, which will then use the newly obtained access token to invoke the API.
  9. The decoded JWT details should be rendered below.

Here is an example of the APIM Javascript Tester rendering the JWT contents:

The response had this JWT

JWT Contents

Fundamentally a JWT is a collection of claims.  Claims returned by UCSD's APIM can be broken into several groups:

  • Standard JWT Claims - part of the JWT spec
  • Invocation Claims - details about how api was called
  • Application Details - details about the application invoking the API
  • User Details - details about the user that the application is working on behalf of

Which claims are included vary based how authentication was done.  For example, using Client Authentication where only the client key and secret are provided, will result in the JWT not having any user claims.  

Some API developers choose to "trust" the application and have the application provide user details as other headers or part of the payload. These details are not verified by the APIM which means that API developers have to be more careful about which applications they grant subscriptions to. Claims in the JWT cannot be spoofed by a "rogue" application as they are independently gathered by the APIM.

Standard Claims

The JWT specification includes a number of possible claims. The JWT contains the following standard claims:

Claim
Value
iss

Issuing entity. This will be the domain of the identity server used to create the JWT.

expExpiration time in Unix format.

Invocation Details

Claim
Value
http://wso2.org/claims/apicontextThe context of the API invoked. This is unique to each API registered in the APIM and can be used to determine which API the user invoked if multiple APIs point to a single backend.
http://wso2.org/claims/versionThe version of the API invoked. Useful if the backend API supports multiple versions of it's interface, although most back end implementations choose to include the version on the URL.
http://wso2.org/claims/keytypeMost APIs send Production/Sandbox (or QA/Dev) requests to different backend. In the case that both go to the same backend service, this value can be used to determine which version was invoked. Specifically if a "PRODUCTION" or "SANDBOX" key was used. Note: on QA we have adjusted the UI to say "QA" and "Dev", but this value will still be "PRODUCTION" or "SANDBOX"
http://wso2.org/claims/usertypeThe type of OAuth 2.0 grant used for authorization. "APPLICATION_USER" for grant types that include a Resource Owner (authorization_code, implicit, resource owner password). "APPLICATION" for those that only have a Client (client credentials). When set to "APPLICATION", no user details will be included.

Application Details

Claim
Value
http://wso2.org/claims/subscriber

The APIM user who registered the application making the invocation. This really shouldn't be used for anything other than contact information, instead use the application name. Eventually we hope to allow teams to jointly manage application registrations, which will make this field even less useful.

http://wso2.org/claims/applicationidThe ID of the registered application. Less descriptive and more brittle than the application name, it may be useful in certain scenarios where high security is needed.
http://wso2.org/claims/applicationname

The name of the registered application that is invoking the API. The Client / Secret pair used during invocation maps to the application registration.

http://wso2.org/claims/applicationtierThe throttling tier of the registered application. Used even less than http://wso2.org/claims/tier.
http://wso2.org/claims/tierThe throttling tier of the subscription used. Almost never used. It can be used to provide different "tiers" of service to different consumers. Which tiers are available to subscribers are selected by the API publisher from a global list maintained by the APIM administrators. Currently UCSD does not utilize this feature and almost all subscriptions select "Unlimited"
http://wso2.org/claims/enduserThe APIM user who invoked the API. This value shouldn't be used as it's their APIM username, which has no meaning outside of the APIM. Instead use the SSO details described below.

User Details

Claim
Value
http://wso2.org/claims/enduserThe APIM user who invoked the API. This value shouldn't be used as it's their APIM username, which has no meaning outside of the APIM. Instead use the SSO details described below.
http://wso2.org/claims/enduserTenantId

The APIM can be setup to segregate users and apis into different tenants. UCSD is not utilizing this feature so this claim has no meaning.

http://wso2.org/claims/roleThe Roles associated with the user in the APIM system. These are not roles from any external source (e.g. AD) and have no meaning outside the APIM.

SSO Details

In addition to the details about the user's APIM account, some of the values provided by UCSD's SSO server are included.  If a given value was not provided by the SSO server, it will be "-" as the integration element doesn't handle null values well.  See http://syswiki.ucsd.edu/index.php/Shibboleth#Shibboleth_attributes for more details on the specific meaning and source of these values.

Claim
SSO Attribute
Value
http://wso2.org/claims/adusernameurn:mace:ucsd.edu:sso:ad:usernameActive Directory User Name - Not always available even if they have an active AD account.
http://wso2.org/claims/departmentcodesurn:mace:ucsd.edu:sso:pps:departmentcodes

The APIM can be setup to segregate users and apis into different tenants. UCSD is not utilizing this feature so this claim has no meaning.

http://wso2.org/claims/eidurn:mace:ucsd.edu:sso:pps:eidEmployee ID
http://wso2.org/claims/emailaddressurn:mace:ucsd.edu:sso:people:long_emailThe long form of the user's UCSD email address, where the name can be longer than 8 characters.
http://wso2.org/claims/givennameurn:mace:ucsd.edu:sso:people:firstnameFirst name
http://wso2.org/claims/lastnameurn:mace:ucsd.edu:sso:people:lastnameLast name
http://wso2.org/claims/networkuseridurn:mace:ucsd.edu:sso:networkuseridkerberos/network username (a.k.a. Mail Account)
http://wso2.org/claims/pidurn:mace:ucsd.edu:sso:isis:pidStudent ID (PID)
http://wso2.org/claims/racfidurn:mace:ucsd.edu:sso:auth:racfidracf/mainframe id (a.k.a. Business Systems account)
http://wso2.org/claims/systemidurn:mace:ucsd.edu:sso:people:affiliateid

persistent, unique identifier for this user. This a GUID and is only relevant to the SOA set of services. Unlike all other identifiers, these will never be recycled and should be used as the user's primary ID in the remote system.

Validating the JWT

The JWT supplied by the APIM is digitally signed by the APIM's certificate.  The certificate is issued by UCSD and signed by a reputable CA.  Please contact lzelus@ucsd.edu if you need a copy of the public certificates used. 

The JWT Spec has the exact details on how to validate a JWT, however there are many libraries that have already implemented the spec and make parsing/validating JWTs quite simple.

------------- Extra Documentation gathered from other sources ---------------

Below here are some extra bits of documentation gathered from around the web, primarily from BYU with whom we collaborate about our usage of WSO2's APIM.  The data below is not all applicable to UCSD's usage, it contains elements specific to other institutions, configurations and scenarios.

JWT Processing Code Example

BYU use of claims and JWT

From this point on we've included some details of how BYU is using JWT and claims.  This is only included to spark future discussion and thought, not as an indication of what is or will be implemented.

Following are claims used by BYU and are provide for reference only

Claim
Value
http://wso2.org/claims/subscriberThe netid of the user that subscribed to this API.
http://wso2.org/claims/applicationidInternal WSO2 application identifier.
http://wso2.org/claims/applicationnameThe name of this application.
http://wso2.org/claims/applicationtierThe throttling tier assigned to this application.
http://wso2.org/claims/apicontext

The context used in this API call (may or may not include version).

http://wso2.org/claims/versionThe version of this API.
http://wso2.org/claims/tierThe throttling tier assigned to this user.
http://wso2.org/claims/keytypeThe type of keys used in this call. Possible values are "PRODUCTION" or "SANDBOX".
http://wso2.org/claims/usertypeThe type of OAuth 2.0 grant used for authorization. "APPLICATION_USER" for grant types that include a Resource Owner (authorization_code, implicit, resource owner password). "APPLICATION" for those that only have a Client (client credentials).
http://wso2.org/claims/enduser

The netid of the resource owner in the form of "netid@carbon.super"

http://wso2.org/claims/enduserTennantId

The WSO2 tenant id. (This value can be ignored since we don't have multiple tenants)

http://wso2.org/claims/client_idThe OAuth 2.0 client id used for authorization. (This value is WSO2 claim but was added by BYU)

BYU Claims

BYU has added a number of claims to make processing of identity information easier for service providers. The content of the Resource Owner and Client claims will be dependent upon which OAuth 2.0 grant type was used for authorization and if there has been a relationship established between the client application and a BYU entity (non-person person). That relationship is defined by placing a entry in the IAM.Credentials table within CESPRD. The entry would have the following values:

CREDENTIAL_NAME - The WSO2 Client Id for the application to be linked to a BYU entity. 

CREDENTIAL_TYPE - 'WSO2_CLIENT_ID'

BYU_ID - The BYU ID of the BYU entity to link this application to.

All other values in the table should be filled in with the appropriate information.

 

Relationship records should only be added for applications under the control of a BYU entity. There is no need to add them for individuals publishing their own applications. Currently there is no defined process for approving and adding these relationship records.

Some UCSD claims are optional based upon the OAuth 2.0 grant type used. For example, if the Client Credentials grant type is used no Resource Owner exists and so the claims dealing with Resource Owner values will not be present in the JWT. The set of possible BYU specific claims are as follows:

 

Claim
Value
http://byu.edu/claims/resourceowner_person_id
The person_id of the Resource Owner
http://byu.edu/claims/resourceowner_byu_id
The byu_id of the Resource Owner
http://byu.edu/claims/resourceowner_net_id
The net_id of the Resource Owner
http://byu.edu/claims/resourceowner_surname
The surname of the Resource Owner
http://byu.edu/claims/resourceowner_surname_position
The position of the surname of the Resource Owner when joining with the rest_of_name.
http://byu.edu/claims/resourceowner_rest_of_name
The rest_of_name of the Resource Owner. Typically the first and middle names.
http://byu.edu/claims/resourceowner_preferred_first_name
The preferred_first_name of the Resource Owner.
http://byu.edu/claims/resourceowner_sort_name
The full name of the Resource Owner combined for sorting purposes.
http://byu.edu/claims/resourceowner_suffix
The suffix (Jr, Sr, etc.) of the name of Resource Owner.
http://byu.edu/claims/resourceowner_prefix
The prefix (Dr, Mr, etc.) of the name of the Resource Owner.
http://byu.edu/claims/client_subscriber_net_id
The net_id of the person that subscribed to the called API. This is also the person that owns the client application in most cases. This is a cleaned up version of the http://wso2.org/claims/subscriber claim.
http://byu.edu/claims/client_claim_source

The source of the name and identifier information in the client claims defining the owner of the client application. Possible values are:

'CLIENT_SUBSCRIBER' - No relationship was found for this client application in the IAM.CREDENTIALS table. All values are based upon the value of the http://byu.edu/claims/client_subscriber_netid claim.

'CLIENT_ID' - A relationship was found for this client application in the IAM.CREDENTIALS table. All values are based upon the byu_id from that relationship.

http://byu.edu/claims/client_person_id
The person_id of the owner of the client application.
http://byu.edu/claims/client_byu_id
The byu_id of the owner of the client application.
http://byu.edu/claims/client_net_id
The net_id of the owner of the client application. Could be blank if no net_id has been defined for a BYU entity.
http://byu.edu/claims/client_surname
The surname of the owner of the client application.
http://byu.edu/claims/client_surname_position
The surname_position of the owner of the client application.
http://byu.edu/claims/client_rest_of_name
The rest_of_name of the owner of the client application.
http://byu.edu/claims/client_preferred_first_name
The preferred_first_name of the owner of the client application.
http://byu.edu/claims/client_sort_name
The full name of the owner of the client application combined for sorting purposes.
http://byu.edu/claims/client_name_suffix
The name suffix of the owner of the client application.
http://byu.edu/claims/client_name_prefix
The name prefix of the owner of the client application.

 

Examples

There are four possible combinations of the values of the http://wso2.org/claims/usertype and http://byu.edu/claims/client_claim_source claims. 

1) OAuth 2.0 Grant type with a Resource Owner and no relationship between the client application and a BYU entity (http://wso2.org/claims/usertype = 'APPLICATION_USER' and http://byu.edu/claims/client_claim_source = 'CLIENT_SUBSCRIBER')

Resource Owner with Subscriber as Client Application Owner

 

{
  "iss""https://api.byu.edu",
  "exp": 1449198389105,
  "http://wso2.org/claims/applicationname""DefaultApplication",
  "http://wso2.org/claims/apicontext""/testapi/RestEchoService/v1",
  "http://wso2.org/claims/tier""Unlimited",
  "http://wso2.org/claims/keytype""PRODUCTION",
  "http://wso2.org/claims/usertype""APPLICATION_USER",
  "http://wso2.org/claims/enduser""bdm4@carbon.super",
  "http://wso2.org/claims/client_id""2hZhnFK3i8dtYaV3xE_RaXE_o0Ma",
  "http://byu.edu/claims/client_claim_source""CLIENT_SUBSCRIBER",
}

 


2) OAuth 2.0 Grant type with a Resource Owner and and existing relationship between the client application and a BYU entity (http://wso2.org/claims/usertype = 'APPLICATION_USER' and http://byu.edu/claims/client_claim_source = 'CLIENT_ID')

Resource Owner and BYU Entity as Client Application Owner

 

{
  "iss""https://api.byu.edu",
  "exp": 1449196008421,
  "http://wso2.org/claims/applicationname""DefaultApplication",
  "http://wso2.org/claims/apicontext""/testapi/RestEchoService/v1",
  "http://wso2.org/claims/tier""Unlimited",
  "http://wso2.org/claims/keytype""PRODUCTION",
  "http://wso2.org/claims/usertype""APPLICATION_USER",
  "http://wso2.org/claims/enduser""bdm4@carbon.super",
  "http://wso2.org/claims/client_id""2hZhnFK3i8dtYaV3xE_RaXE_o0Ma",
}

 


3) OAuth 2.0 Grant type with no Resource Owner and no relationship between the client application and a BYU entity (http://wso2.org/claims/usertype = 'APPLICATION' and http://byu.edu/claims/client_claim_source = 'CLIENT_SUBSCRIBER')

No Resource Owner with Subscriber as Client Application Owner


4) OAuth 2.0 Grant type with no Resource Owner and an existing relationship between the client application and a BYU entity (http://wso2.org/claims/usertype = 'APPLICATION' and http://byu.edu/claims/client_claim_source = 'CLIENT_ID')

No Resource Owner and BYU Entity as Client Application Owner

 

  • No labels