Create API Gateway Deployments

With your functions ready, you can integrate and test the Native authentication mechanism for JWT validation with Oracle Identity Cloud Service.

Create API Gateway Deployment With Native JWT Validation

By using the Oracle Cloud Infrastructure Gateway Native JWT Validation feature, it is possible to add a Java Web Token (JWT)-based Authentication Policy for your deployment.

This JWT type allows you to specify the required data to perform the validation of the incoming Access Token (via Header or Parameter). The policy requires the follwing information:

  • Allowed Issuers: Token issuers. Several OAuth servers are suported, but in this case you will use https://identity.oraclecloud.com/.
  • Audiences: The resources to be allowed to access for this token.
  • Public Keys: The Json Web Key Set (JWKS) to be used to validate the token, within the issuers and audiences. Two kinds of JWKS are allowed:
    • Static Keys: With this option you need to specify the JWKS manually using JSON format, which should have the required properties according to RFC 7517 Section 4.
    • Remote Keys: With this option, you need to specify a URL from which the JWKS can be consumed using REST. A limitation of this feature is that the URL specified needs to be unprotected, as currently this feature does not support the ability to read protected URLs to retrieve the JWKS.
  • Advanced Options:
    • Max Clow skew in seconds: If API Gateway and the Identity Provider have some differences in timing, this value allows you to adjust the token validity window time to try to align timing between the two services.
    • Claims: To verify the claims if needed of the incoming token. For example client_id claim or user_id claim.

Create a new Deployment name in your API Gateway with a Route to reach the function created in the previous steps,by using the Endpoint and JWT Validation. In this example, the deployment is named: my_jwt_test.

  1. In the Oracle Cloud Infrastructure console, from the API Gateway page, select the active gateway by clicking its name.
  2. Under Resources, select Deployments, and then select Create Deployment.
  3. Configure the Authentication Policy with the following values:
    • Authentication Type: JWT
    • Authentication Token: Header
    • Header Name: Authorization
    • Authentication Scheme: Bearer
    • Enable Anonymous Access: enabled
  4. Add the Oracle Identity Cloud Service domain as an allowed issuer, so you can use it as a token generator. In Issuers, set Allowed Issuers to https://identity.oraclecloud.com/
  5. Add an audience. Set an Allowed Audience to the URL of your Oracle Identity Cloud Service Oracle Functions Application. For example, https://myinstance.apigateway.mydc.oci.customer-oci.com.
    The Audiences to be validated should be the ones for the resources that the generated token needs to be able to access. In this case, we expect the token from the Oracle Identity Cloud Service App that is the client of the Oracle Functions Oracle Identity Cloud Service App Resource owner, that has as resource scope the primary audiences of the Oracle Functions Oracle Identity Cloud Service App.
  6. Add the JWK to be used to validate the incoming JWT token; either remote or static JWKS. To add a Remote JWKS:
    1. Access the Oracle Identity Cloud Service console.
    2. Select Settings, and then select Default Settings.
    3. If it is not already enabled, select Access Signing Certificate, click Save, and then click Yes.
    4. Access the JWK URL for your Oracle Identity Cloud Service instance. For example: https://idcs-myinstance.identity.dc1.oraclecloud.com/admin/v1/SigningCert/jwk.
    5. After you have validated that you can see the JWK URL, go back to API Gateway and configure the Public Keys. Set the Type to Remote JWKS, and set the URI to the URL you just validated.
  7. To add a static JWKS:
    1. Define the Static Key form. To do this, you need to request the JWK for the Oracle Identity Cloud Service. You can do this with curl. For example:
      ## Get access token to be able to invoke protected /admin/v1/SigningCert/jwk endpoint.
      # Clientid and ClientSecret should be from an existing IDCS Application in the stripe.
      #
      $ curl -X POST -u "<clientId>:<clientSecret>" https://idcs-myinstance.identity.dc1.oraclecloud.com/oauth2/v1/token -d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"
       
       
      export jwtToken="<RETRIEVED_TOKEN>"
       
      ## Get JWK
      $ curl -X GET  https://idcs-myinstance.identity.dc1.oraclecloud.com/admin/v1/SigningCert/jwk -H "Authorization: Bearer ${jwtToken}"
       
      {
          "keys":[{
              "kty":"RSA",
              "x5t#S256":"<value>",
              "e":"<value>",
              "x5t":"<value>",
              "kid":"SIGNING_KEY",
              "x5c":["<value>"],
              "key_ops":["encrypt","verify","wrapKey"],
              "alg":"RS256",
              "n":"<value>"
          }]
      }
    2. Configure the Public Keys in API Gateway. Set the Type to Static Keys. Set the Key ID to SIGNING_KEY, and the Format to JSON Web Key. Paste in a JSON Web Key, using only the following subset of the values you got from Oracle Identity Cloud Service.
      Only certain properties of the JWK key are currently supported by API Gateway. Instead of the key_ops property, use the use property.
      {
              "kty":"RSA",
              "e":"<value>",
              "kid":"SIGNING_KEY",
              "use":"sig",
              "alg":"RS256",   
              "n":"<value>"
      }
  8. Optionally, you can add additional validation in the Verify Claims section. Add a client_id claim to allow only values that correspond to the Oracle Identity Cloud Service Application associated with your Oracle Visual Builder application. If you have multiple Oracle Visual Builder applications, and the OAuth tokens will be generated using several Oracle Visual Builder Oracle Identity Cloud Service Apps, you will need to add all of the Oracle Identity Cloud Service client IDs to this verification step. Set the Claim Key to client_id, enter one or more Claim Values, and select the Required check box.
  9. Optionally, you can configure CORS to allow requests from the specified domains. For example, you may need to allow the Oracle Visual Builder server hostnames as permitted origins of requests. Set Allowed Origins to the URLs of your servers, Exposed Headers to Authorization, Allowed Headers to Authorization, Enable Allow Credentials to Yes, and Allowed Methods to GET,POST.
  10. Create a route to point to your function, such as the sample Function saasopportunitiesfn. Set Path to /assertion/facall, Methods to GET and POST, Type to Oracle Functions, make sure the Application in <your compartment> has the correct compartment selected, set the application to your application name such as myapplication, and set Function Name to your function name, such as saasopportunitiesfn.
After you save your changes, you can review the contents of your API Gateway Deployment my_jwt_test payload.

Test Endpoint REST Invocation

To test the new endpoint REST invocation, you can use the Get New Access Token feature of Postman.

Please note that if you use the generated token in the following steps you will not be able to reach Oracle Fusion Applications Cloud Service endpoints directly, because the token was generated with the Oracle Identity Cloud Service App from Oracle Visual Builder and it is only able to reach Oracle Functions with the current configuration, per the Scopes you previously set up. Also, if you use a different Oracle Identity Cloud Service App to generate the token, and that application lacks the grants to reach the Oracle Functions Resource Scope, API Gateway will not allow the request (it will return a 401 error) because you added the Audience of Oracle Functions Oracle Identity Cloud Service Resource. If you added Claims client-id verifications, API Gateway will ensure the tokens match only with thoseOracle Identity Cloud Service Apps client_ids specified.

Use the following parameters to test:

  • Grant Type: Password Credentials - This Grant Type is used to ensure that the username provided will be the subject in the generated token.
  • Access Token URL: Your Oracle Identity Cloud Service instance OAuth URL. For example, https://idcs-myinstance.identity.dc1.oraclecloud.com/oauth2/v1/token.
  • Username: A user that exists in both Oracle Identity Cloud Service and Oracle Fusion Applications Cloud Service with appropriate privileges in both.
  • Password: Enter the password for this user.
  • ClientId: The ID of the Oracle Identity Cloud Service Client Oracle Functions Resource associated with Oracle Visual Builder.
  • ClientSecret: The client secret of the Oracle Identity Cloud Service App Client Oracle Functions Resource associated with Oracle Visual Builder
  • Scope: This scope should match with the Oracle Functions Oracle Identity Cloud Service App provided Resources. For example, https://myservice.apigateway.dc1.oci.customer-oci.com/saasextension
  1. Invoke the route configured to point to your asserter function using Postman and the parameters listed above.
  2. Alternatively, use curl. For example:
    curl --location --request GET 'https://myservice.apigateway.dc1.oci.customer-oci.com/saasextension/assertion/facall' \
    --header 'Authorization: Bearer <JWT_TOKEN>'
You should get a result from either tool, similar to the following:
{
  "principal": "mary.jane",
  "gotPrincipalFrom": "BEARER",
  "statusCode": "200",
  "response": {
    "items": [],
    "count": 0,
    "hasMore": false,
    "limit": 25,
    "offset": 0,
    "links": [
      {
        "rel": "self",
        "href": "https://myfusionservice.fa.dc1.oraclecloud.com:443/fscmRestApi/resources/11.13.18.05/expenses",
        "name": "expenses",
        "kind": "collection"
      }
    ]
  }
}

Optionally Create API Gateway Deployment With Custom Authentication

Use this approach if you choose to use a custom Authentication Function to validate the Bearer Token for inbound calls to API Gateway Endpoints.

This is the optional Function you have defined if you followed the stetps from the Optionally Define an Authentication Function in Oracle Cloud Infrastructure section.

  1. To deploy the API gateway, from the API Gateway page, select the active gateway by clicking its name.
  2. Under Resources, click Deployments, and then click Create Deployment.
  3. Using the From Scratch mode, you can click through the wizard to deploy the API gateway.
    Alternatively, you can choose to Upload a deployment definition file, as described below.

The following code snippet is an example Oracle Cloud Infrastructure API deployment specification JSON file you could use to deploy instead of using the wizard. Within this file we can see:

  • Lines 1-8: An authentication request policy. This is the definition which instructs that for any request in this deployment, first call this function (functionId), passing the tokenHeader, and if it returns true then proceed, otherwise respond with an HTTP unauthorized message.
  • Lines 9-17: A CORS definition to manage and control cross-origin resource sharing.
  • Lines 18-43: Two URL entry points/VERBs to individual functions in FaaS.
{
    "requestPolicies": {
      "authentication": {
        "type": "CUSTOM_AUTHENTICATION",
        "isAnonymousAccessAllowed": true,
        "functionId": "OCID1.fnfunc.oc1.phx.xxxxxxxxxxxxxxx",
        "tokenHeader": "Authorization"
      }
      "cors":{ 
         "allowedOrigins": [<list-of-origins>], 
         "allowedMethods": [<list-of-methods>], 
         "allowedHeaders": [<list-of-implicit-headers>], 
         "exposedHeaders": [<list-of-exposed-headers>], 
         "isAllowCredentialsEnabled": <true|false>, 
         "maxAgeInSeconds": <seconds> 
      } 
    },
    "routes": [
      {
        "path": "/opportunities",
        "methods": [
          "GET"
        ],
        "requestPolicies": {},
        "backend": {
          "type": "ORACLE_FUNCTIONS_BACKEND",
          "functionId": "OCID1.fnfunc.oc1.phx.xxxxxxxxxxxxxxx"
 
        }
      },
      {
        "path": "/opportunities/{optyid}",
        "methods": [
          "PATCH"
        ],
        "requestPolicies": {},
        "backend": {
          "type": "ORACLE_FUNCTIONS_BACKEND",
          "functionId": "OCID1.fnfunc.oc1.phx.xxxxxxxxxxxxxxx"
        }
      }
    ]
  }
</seconds></true|false></list-of-exposed-headers></list-of-implicit-headers></list-of-methods></list-of-origins>