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:
...
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:
...
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. |
exp | Expiration time in Unix format. |
Invocation Details
Claim | Value |
---|---|
http://wso2.org/claims/apicontext | The 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/version | The 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/keytype | Most 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/usertype | The 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/applicationid | The 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/applicationtier | The throttling tier of the registered application. Used even less than http://wso2.org/claims/tier. |
http://wso2.org/claims/tier | The 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/enduser | The 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/enduser | The 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/role | The 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/adusername | urn:mace:ucsd.edu:sso:ad:username | Active Directory User Name - Not always available even if they have an active AD account. |
http://wso2.org/claims/departmentcodes | urn: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/eid | urn:mace:ucsd.edu:sso:pps:eid | Employee ID |
http://wso2.org/claims/emailaddress | urn:mace:ucsd.edu:sso:people:long_email | The long form of the user's UCSD email address, where the name can be longer than 8 characters. |
http://wso2.org/claims/givenname | urn:mace:ucsd.edu:sso:people:firstname | First name |
http://wso2.org/claims/lastname | urn:mace:ucsd.edu:sso:people:lastname | Last name |
http://wso2.org/claims/networkuserid | urn:mace:ucsd.edu:sso:networkuserid | kerberos/network username (a.k.a. Mail Account) |
http://wso2.org/claims/pid | urn:mace:ucsd.edu:sso:isis:pid | Student ID (PID) |
http://wso2.org/claims/racfid | urn:mace:ucsd.edu:sso:auth:racfid | racf/mainframe id (a.k.a. Business Systems account) |
http://wso2.org/claims/systemid | urn:mace:ucsd.edu:sso:people:affiliateid | A 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. |
http://wso2.org/claims/ucpathemplid | urn:mace:ucsd.edu:sso:ucpath:emplid | UCPath employee ID |
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.
...
Code Block | ||
---|---|---|
| ||
import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.cert.CertificateException; import java.util.Map.Entry; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.JsonNode; import com.mashape.unirest.http.Unirest; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; public class DecodeJwtFromAPIM { private static final Logger log = LoggerFactory.getLogger(DecodeJwtFromAPIM.class); private static final String ConsumerSecret = "a6kF0HyNaergsVSGaCKhlbRtSXob"; private static final String ConsumerKey = "5hJFay5newu3Pi1affMJgkk7LpIa"; private static final String APIM_PUBLIC_KEY_PATH = "/api-qa.ucsd.edu.pub.jks"; private static final String APIM_CERTIFICATE_ALIAS = "api-qa.ucsd.edu"; private static final String JKS_PASSWORD = "middleware"; @Test public void test() throws Exception { HttpResponse<JsonNode> jsonResponse = Unirest.post("https://api-qa.ucsd.edu:8243/token") .field("grant_type", "client_credentials").basicAuth(ConsumerKey, ConsumerSecret).asJson(); log.debug("Response from token request: " + jsonResponse.getBody()); String token = jsonResponse.getBody().getObject().getString("access_token"); log.debug("Access Token: " + token); jsonResponse = Unirest.get("https://api-qa.ucsd.edu:8243/echo/1.0.0") .header("Authorization", "Bearer " + token) .asJson(); log.debug("Response from echo request: " + jsonResponse.getBody()); String jwtHeader = jsonResponse.getHeaders().getFirst("X-JWT-Assertion"); log.debug("X-JWT-Assertion: " + jwtHeader); PublicKey publicKey = loadPublicKey(); Claims claims = Jwts.parser() .setSigningKey(publicKey) .parseClaimsJws(jwtHeader) .getBody(); for (Entry<String, Object> claim : claims.entrySet()) { log.debug("Claim {} ==> {}", claim.getKey(), claim.getValue()); } } private PublicKey loadPublicKey() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { try (InputStream is = DecodeJwtFromAPIM.class.getResourceAsStream(APIM_PUBLIC_KEY_PATH)) { KeyStore ks = KeyStore.getInstance("JKS"); ks.load(is, JKS_PASSWORD.toCharArray()); return ks.getCertificate(APIM_CERTIFICATE_ALIAS).getPublicKey(); } } } |
------------- Extra Documentation gathered from other sources ---------------
...
Following are claims used by BYU and are provide for reference only
Claim | Value |
---|---|
http://wso2.org/claims/subscriber | The netid of the user that subscribed to this API. |
http://wso2.org/claims/applicationid | Internal WSO2 application identifier. |
http://wso2.org/claims/applicationname | The name of this application. |
http://wso2.org/claims/applicationtier | The 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/version | The version of this API. |
http://wso2.org/claims/tier | The throttling tier assigned to this user. |
http://wso2.org/claims/keytype | The type of keys used in this call. Possible values are "PRODUCTION" or "SANDBOX". |
http://wso2.org/claims/usertype | The 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_id | The 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:
...
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.
...
Resource Owner with Subscriber as Client Application Owner
...
{ "exp" : 1449198389105, } |
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
{ "exp" : 1449196008421, } |
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
...
{ "exp" : 1449198083615, } |
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
{ "exp" : 1449196866334, } |
...