Using a JWT_AUTHENTICATION Authentication Request Policy (no longer recommended)
When using an authentication request policy of type JWT_AUTHENTICATION, before an end user can access an API deployment that uses JSON Web Tokens (JWTs) for authentication and authorization, they must obtain a JWT from an identity provider.
In earlier releases, you might have created authentication request policies of type JWT_AUTHENTICATION to use JWTs for authentication.
If you are creating new authentication request policies to use JWTs, we now recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead (see Using the Console to Add Token Authentication and Authorization Request Policies and Editing a JSON File to Add Token Authentication and Authorization Request Policies). We also recommend you migrate existing JWT_AUTHENTICATION request policies to TOKEN_AUTHENTICATION policies.
Note that existing JWT_AUTHENTICATION request policies are currently still supported. Also note that although you can create new JWT_AUTHENTICATION request policies by defining the API deployment specification in a JSON file (as described in the original instructions in this section), we recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead.
When calling an API deployed on an API gateway, the API client provides the JWT as a query parameter or in the header of the request. The API gateway validates the JWT using a corresponding public verification key provided by the issuing identity provider. Using the API deployment's JWT_AUTHENTICATION authentication request policy, you can configure how the API gateway validates JWTs:
- You can configure the API gateway to retrieve public verification keys from the identity provider at runtime. In this case, the identity provider acts as the authorization server.
- You can configure the API gateway in advance with public verification keys already issued by an identity provider (referred to as 'static keys'), enabling the API gateway to verify JWTs locally at runtime without having to contact the identity provider. The result is faster token validation.
To add a new JWT_AUTHENTICATION authentication and authorization request policy to an API deployment specification in a JSON file:
-
Add an
authenticationrequest policy that applies to all routes in the API deployment specification:-
Insert a
requestPoliciessection before theroutessection, if one doesn't exist already. For example:{ "requestPolicies": {}, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] } -
Add the following
authenticationpolicy to the newrequestPoliciessection.{ "requestPolicies": { "authentication": { "type": "JWT_AUTHENTICATION", "isAnonymousAccessAllowed": <true|false>, "issuers": ["<issuer-url>", "<issuer-url>"], <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>">, "tokenAuthScheme": "<authentication-scheme>", "audiences": ["<intended-audience>"], "publicKeys": { "type": <"REMOTE_JWKS"|"STATIC_KEYS">, <public-key-config> }, "verifyClaims": [ {"key": "<claim-name>", "values": ["<acceptable-value>", "<acceptable-value>"], "isRequired": <true|false> } ], "maxClockSkewInSeconds": <seconds-difference> } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] }where:
-
"isAnonymousAccessAllowed": <true|false>optionally indicates whether unauthenticated (that is, anonymous) end users can access routes in the API deployment specification. If you never want anonymous end users to be able to access routes, set this property tofalse. If you don't include this property in theauthenticationpolicy, the default offalseis used. Note that if you do include this property and set it totrue, you also have to explicitly specify every route to which anonymous access is allowed by setting thetypeproperty to"ANONYMOUS"in each route'sauthorizationpolicy. -
<issuer-url>is the URL (or a text string) for an identity provider that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, enterhttps://identity.oraclecloud.com/. You can specify one or multiple identity providers (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI. -
<"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>">indicates whether it is a request header that contains the JWT (and if so, the name of the header), or a query parameter that contains the JWT (and if so, the name of the query parameter). Note that you can specify either"tokenHeader": "<token-header-name>"or"tokenQueryParam": "<token-query-param-name>">, but not both. -
<tokenAuthScheme>is the name of the authentication scheme to use if the JWT is contained in a request header. For example,"Bearer". -
<intended-audience>is a value that is allowed in the audience (aud) claim of a JWT to identify the intended recipient of the token. For example, the audience could be, but need not be, the API gateway's hostname. You can specify one audience or multiple audiences (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI. -
"type": <"REMOTE_JWKS"|"STATIC_KEYS">indicates how you want the API gateway to validate JWTs using public verification keys. SpecifyREMOTE_JWKSto configure the API gateway to retrieve up to ten public verification keys from the identity provider at runtime. SpecifySTATIC_KEYSto configure the API gateway with up to ten public verification keys already issued by an identity provider (enabling the API gateway to verify JWTs locally without having to contact the identity provider). -
<public-key-config>provides the details of JWT validation, according to whether you specified"REMOTE_JWKS"or"STATIC_KEYS"as the value of"type":as follows:-
If you specified
"type": "REMOTE_JWKS"to configure the API gateway to validate JWTs by retrieving public verification keys from the identity provider at runtime, provide details as follows:"publicKeys": { "type": "REMOTE_JWKS", "uri": "<uri-for-jwks>", "maxCacheDurationInHours": <cache-time>, "isSslVerifyDisabled": <true|false> }where:
-
"uri": "<uri-for-jwks>"specifies the URI from which to retrieve the JSON Web Key Set (JWKS) to use to verify the signature on JWTs. For more information about the URI to specify, see Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI. Note the following:- The URI must be routable from the subnet containing the API gateway on which the API is deployed.
- If the API gateway fails to retrieve the JWKS, all requests to the API deployment will return an HTTP 500 response code. Refer to the API gateway's execution log for more information about the error (see Adding Logging to API Deployments).
- Certain key parameters must be present in the JWKS to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures).
- The JWKS can contain up to ten keys.
-
"maxCacheDurationInHours": <cache-time>specifies the number of hours (between 1 and 24) the API gateway is to cache the JWKS after retrieving it. -
"isSslVerifyDisabled": <true|false>indicates whether to disable SSL verification when communicating with the identity provider. Oracle recommends not setting this option totruebecause it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
For example:
"publicKeys": { "type": "REMOTE_JWKS", "uri": "https://www.somejwksprovider.com/oauth2/v3/certs", "maxCacheDurationInHours": 3, "isSslVerifyDisabled": false } -
-
If you specified
"type": "STATIC_KEYS", the details to provide depend on the format of the key already issued by the identity provider (regardless of format, you can specify up to ten keys):-
If the static key is a JSON Web Key, specify
"format": "JSON_WEB_KEY", specify the identifier of the static key used to sign the JWT as the value of the"kid"parameter, and provide values for other parameters to verify the JWT's signature.For example:
"publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "JSON_WEB_KEY", "kid": "master_key", "kty": "RSA", "n": "0vx7agoebGc...KnqDKgw", "e": "AQAB", "alg": "RS256", "use": "sig" } ]Note that certain parameters must be present in the static key to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures). Also note that
RSAis currently the only supported key type (kty). -
If the static key is a PEM-encoded public key, specify
"format": "PEM", specify the identifier of the static key used to sign the JWT as the value of"kid", and provide the key as the value of"key".For example:
"publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "PEM", "kid": "master_key" "key": -----BEGIN PUBLIC KEY-----XsEiCeYgglwW/KAhSSNRVdD60QlXYMWHOhXzSFDZCLf1WXxKMZCiMvVrsBIzmFEXnFmcsO2mxwlL5/8qQudomoP+yycJ2gWPIgqsZcQRheJWxVC5ep0MeEHlvLnEvCi9utpAnjrsZCQ7plfZVPX7XORvezwqQhBfYzwA27M2FgOOs8DOIYfqQ1Ki3DMqEppFnjLcjgQtknbTlT7YgG6tzobwig8M2KIrPjJ0BmbJAFH-----END PUBLIC KEY----- } ]Note that the
-----BEGIN PUBLIC KEY-----and-----END PUBLIC KEY-----markers are required.
-
-
-
verifyClaimsoptionally specifies additional claim names and values for one or more additional claims to validate in a JWT (up to a maximum of ten).-
"key": "<claim-name>"is the name of a claim that can be, or must be, included in a JWT. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular identity provider. -
"values": ["<acceptable-value>", "<acceptable-value>"](optionally) indicates one or more acceptable values for the claim. -
"isRequired": <true|false>indicates whether the claim must be included in the JWT.
Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported
-
-
maxClockSkewInSeconds: <seconds-difference>optionally specifies the maximum time difference between the system clocks of the identity provider that issued a JWT and the API gateway. The value you specify is taken into account when the API gateway validates the JWT to determine whether it is still valid, using the not before (nbf) claim (if present) and the expiration (exp) claim in the JWT. The minimum (and default) is0, the maximum is120.
For example, the following
authenticationpolicy configures the API gateway with a public verification key already issued by an identity provider to validate the JWT in the Authorization request header:{ "requestPolicies": { "authentication": { "type": "JWT_AUTHENTICATION", "isAnonymousAccessAllowed": false, "issuers": ["https://identity.oraclecloud.com/"], "tokenHeader": "Authorization", "tokenAuthScheme": "Bearer", "audiences": ["api.dev.io"], "publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "JSON_WEB_KEY", "kid": "master_key", "kty": "RSA", "n": "0vx7agoebGc...KnqDKgw", "e": "AQAB", "alg": "RS256", "use": "sig" } ] }, "verifyClaims": [ { "key": "is_admin", "values": ["service:app", "read:hello"], "isRequired": true } ], "maxClockSkewInSeconds": 10 } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" } } ] } -
-
-
Add an
authorizationrequest policy for each route in the API deployment specification:-
Insert a
requestPoliciessection after the first route'sbackendsection, if one doesn't exist already. For example:{ "requestPolicies": { "authentication": { "type": "JWT_AUTHENTICATION", "isAnonymousAccessAllowed": false, "issuers": ["https://identity.oraclecloud.com/"], "tokenHeader": "Authorization", "tokenAuthScheme": "Bearer", "audiences": ["api.dev.io"], "publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "JSON_WEB_KEY", "kid": "master_key", "kty": "RSA", "n": "0vx7agoebGc...KnqDKgw", "e": "AQAB", "alg": "RS256", "use": "sig" } ] }, "verifyClaims": [ { "key": "is_admin", "values": ["service:app", "read:hello"], "isRequired": true } ], "maxClockSkewInSeconds": 10 } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": {} } ] } -
Add the following
authorizationpolicy to therequestPoliciessection:{ "requestPolicies": { "authentication": { "type": "JWT_AUTHENTICATION", "isAnonymousAccessAllowed": false, "issuers": ["https://identity.oraclecloud.com/"], "tokenHeader": "Authorization", "tokenAuthScheme": "Bearer", "audiences": ["api.dev.io"], "publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "JSON_WEB_KEY", "kid": "master_key", "kty": "RSA", "n": "0vx7agoebGc...KnqDKgw", "e": "AQAB", "alg": "RS256", "use": "sig" } ] }, "verifyClaims": [ { "key": "is_admin", "values": ["service:app", "read:hello"], "isRequired": true } ], "maxClockSkewInSeconds": 10 } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": { "authorization": { "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">, "allowedScope": [ "<scope>" ] } } } ] }where:
-
"type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">indicates how to grant access to the route:-
"AUTHENTICATION_ONLY": Only grant access to end users that have been successfully authenticated. In this case, the"isAnonymousAccessAllowed"property in the API deployment specification'sauthenticationpolicy has no effect. -
"ANY_OF": Only grant access to end users that have been successfully authenticated, provided the JWT'sscopeclaim includes one of the access scopes you specify in theallowedScopeproperty. In this case, the"isAnonymousAccessAllowed"property in the API deployment specification'sauthenticationpolicy has no effect. -
"ANONYMOUS": Grant access to all end users, even if they have not been successfully authenticated. In this case, you must explicitly set the"isAnonymousAccessAllowed"property totruein the API deployment specification'sauthenticationpolicy.
-
-
"allowedScope": [ "<scope>" ]is a comma-delimited list of one or more strings that correspond to access scopes included in the JWT'sscopeclaim. In this case, you must set thetypeproperty to"ANY_OF"(the"allowedScope"property is ignored if thetypeproperty is set to"AUTHENTICATION_ONLY"or"ANONYMOUS"). Also note that if you specify more than one scope, access to the route is granted if any of the scopes you specify is included in the JWT'sscopeclaim.
For example, the following request policy defines a
/helloroute that only allows authenticated end users with theread:helloscope to access it:{ "requestPolicies": { "authentication": { "type": "JWT_AUTHENTICATION", "isAnonymousAccessAllowed": false, "issuers": ["https://identity.oraclecloud.com/"], "tokenHeader": "Authorization", "tokenAuthScheme": "Bearer", "audiences": ["api.dev.io"], "publicKeys": { "type": "STATIC_KEYS", "keys": [ { "format": "JSON_WEB_KEY", "kid": "master_key", "kty": "RSA", "n": "0vx7agoebGc...KnqDKgw", "e": "AQAB", "alg": "RS256", "use": "sig" } ] }, "verifyClaims": [ { "key": "is_admin", "values": ["service:app", "read:hello"], "isRequired": true } ], "maxClockSkewInSeconds": 10 } }, "routes": [ { "path": "/hello", "methods": ["GET"], "backend": { "type": "ORACLE_FUNCTIONS_BACKEND", "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq" }, "requestPolicies": { "authorization": { "type": "ANY_OF", "allowedScope": [ "read:hello" ] } } } ] } -
- Add an
authorizationrequest policy for all remaining routes in the API deployment specification.
Note
If you don't include an
authorizationpolicy for a particular route, access is granted as if such a policy does exist and thetypeproperty is set to"AUTHENTICATION_ONLY". In other words, regardless of the setting of theisAnonymousAccessAllowedproperty in the API deployment specification'sauthenticationpolicy:- only authenticated end users can access the route
- all authenticated end users can access the route regardless of access scopes in the JWT's
scopeclaim - anonymous end users cannot access the route
-
- Save the JSON file containing the API deployment specification.
-
Use the API deployment specification when you create or update an API deployment in the following ways:
- by specifying the JSON file in the Console when you select the Upload an existing deployment API option
- by specifying the JSON file in a request to the API Gateway REST API
For more information, see Deploying an API on an API Gateway by Creating an API Deployment and Updating an API Gateway.
- (Optional) Confirm the API has been deployed successfully by calling it (see Calling an API Deployed on an API Gateway).
Example: Migrating a JWT_AUTHENTICATION Request Policy to a TOKEN_AUTHENTICATION Request Policy
This section shows an example of an existing JWT_AUTHENTICATION request policy migrated to a TOKEN_AUTHENTICATION policy.
One way to approach the migration is to create an empty TOKEN_AUTHENTICATION request policy, and then populate it with values from the JWT_AUTHENTICATION request policy
Before Migration:
The original JWT_AUTHENTICATION request policy, before migration:
{
"requestPolicies": {
"authentication": {
"type": "JWT_AUTHENTICATION",
"isAnonymousAccessAllowed": false,
"issuers": ["https://identity.oraclecloud.com/"],
"tokenHeader": "Authorization",
"tokenAuthScheme": "Bearer",
"audiences": ["api.dev.io"],
"publicKeys": {
"type": "STATIC_KEYS",
"keys": [
{
"format": "JSON_WEB_KEY",
"kid": "master_key",
"kty": "RSA",
"n": "0vx7agoebGc...KnqDKgw",
"e": "AQAB",
"alg": "RS256",
"use": "sig"
}
]
},
"verifyClaims": [
{
"key": "is_admin",
"values": ["service:app", "read:hello"],
"isRequired": true
}
],
"maxClockSkewInSeconds": 10
}
},
"routes": [
{
"path": "/hello",
"methods": ["GET"],
"backend": {
"type": "ORACLE_FUNCTIONS_BACKEND",
"functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
},
"requestPolicies": {
"authorization": {
"type": "ANY_OF",
"allowedScope": [ "read:hello" ]
}
}
}
]
}After Migration:
The new TOKEN_AUTHENTICATION request policy populated with values from the original JWT_AUTHENTICATION request policy:
{
"requestPolicies": {
"authentication": {
"type": "TOKEN_AUTHENTICATION",
"isAnonymousAccessAllowed": false,
"tokenHeader": "Authorization",
"tokenAuthScheme": "Bearer",
"maxClockSkewInSeconds": 10,
"validationPolicy": {
"type": "STATIC_KEYS",
"keys": [
{
"format": "JSON_WEB_KEY",
"kid": "master_key",
"kty": "RSA",
"n": "0vx7agoebGc...KnqDKgw",
"e": "AQAB",
"alg": "RS256",
"use": "sig"
}
],
"additionalValidationPolicy": {
"audiences": [
"api.dev.io"
],
"verifyClaims": [
{
"key": "is_admin",
"values": [
"service:app",
"read:hello"
],
"isRequired": true
}
],
"issuers": [
"https://identity.oraclecloud.com/"
]
}
}
}
},
"routes": [
{
"path": "/hello",
"methods": [
"GET"
],
"backend": {
"type": "ORACLE_FUNCTIONS_BACKEND",
"functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
},
"requestPolicies": {
"authorization": {
"type": "ANY_OF",
"allowedScope": [
"read:hello"
]
}
}
}
]
}