Note:

Customize your API Security using OCI API Gateway and OCI Functions

Introduction

Discover the seamless synergy between Oracle Cloud Infrastructure (OCI) Functions and OCI API Gateway to implement a custom authentication method for your APIs and how functions can retrieve arguments from the API gateway.

OCI API Gateway

The OCI API Gateway service enables you to publish APIs with private endpoints that are accessible from within your network, and which you can expose with public IP addresses if you want them to accept internet traffic. The endpoints support API validation, request and response transformation, CORS, authentication and authorization, and request limiting.

Using the OCI API Gateway service, you create one or more API gateways in a regional subnet to process traffic from API clients and route it to backend services. You can use a single API gateway to link multiple backend services (such as OCI Load Balancer, OCI Compute instances, and OCI Functions) into a single consolidated API endpoint.

OCI Functions

OCI Functions is a fully managed, multi-tenant, highly scalable, on-demand, Functions-as-a-Service platform. It is built on enterprise-grade OCI and powered by the Fn Project open source engine. Use OCI Functions when you want to focus on writing code to meet business needs.

Note:

Objective

Prerequisites

Task 1: Set up Dynamic Groups

Log in to the OCI Console, navigate to your domain, click Dynamic Groups and create groups with the following information.

Task 2: Create Policies

Go to the OCI Console, navigate to Policies and create policies with the following information.

Task 3: Create an OCI Container Registry

  1. Go to the OCI Console, navigate to Developer Services, Containers & Artifacts, select Container registry and click Create repository to create a private repository for the function image.

    • Repository name: Enter functions/authorizationfunctionjava.

      repository creation

  2. Check the repositories and take a note of the Namespace.

    repository namespace

  3. Open the OCI Cloud Shell where you should have OCI CLI and Docker installed, and proceed with the log in on the registry. Check what is the correct URL for your region. In this tutorial, we are using Brazil East (Sao Paulo) where the registry URL is gru.ocir.io.

    docker login -u 'yourRepositoryNamespace/oracleidentitycloudservice/yourUserLogin' gru.ocir.io
    Password: YOUR_AUTH_TOKEN_CREATED_EARLIER
    

    docker login

Task 4: Create a Java OCI Functions as an Authorizer Function

Note: Ensure you select your private subnet.

  1. Go to the OCI Console, navigate to Developer Services, Functions, Applications and click Create application.

    create application

  2. Launch OCI Cloud Shell where you have Docker, the OCI CLI, and the Fn Project CLI installed and run the following commands to initialize the function.

    Note: If you followed the tasks, your Docker login command should have already been executed, if not, proceed with the Docker login step in Task 3.

    Go to the OCI Console, navigate to Developer Services, Functions, Applications, select your application and click Getting started. Run the following commands.

    fn list context
    fn use context sa-saopaulo-1
    fn update context oracle.compartment-id PASTE_YOUR_COMPARTMENT_OCID
    fn update context registry gru.ocir.io/PASTE_YOUR_REGISTRY_NAMESPACE/functions
    

    Note: In this tutorial, we are using Brazil East(Sao Paulo) region, if you are using a different region, you need to change the registry location.

  3. Download the Java function sample code from here: authorizationfunctionjava.tar and upload it to your OCI Cloud Shell and then proceed to unzip the file.

    # check your file is there
    ls -lrt
    # create your directory
    mkdir authorizationfunctionjava
    # unzip the file
    tar -xvf authorizationfunctionjava.tar -C authorizationfunctionjava
    cd authorizationfunctionjava/
    

    unzip tar file

    This simple Java code receives two parameters token and customer. It also retrieves a third parameter from a system environment variable defined in the function configuration.

    Note: Ensure that the parameter names in handleRequest(Input input) method are same as the names used in the API gateway configuration. This ensures that the API gateway correctly passes the parameters to the authorizer function.

    java code

    This code snippet validates the input and returns a specific response.

    validation

    result

    For more information on the required response format and parameters, see Creating an Authorizer Function.

  4. Run the following command to build the code and deploy the function.

    cd authorizationfunctionjava/
    ls -lart
    fn deploy --app chafikFunctions
    

    build

    build

  5. Create several configurations to store your customer credentials for testing the function validation.

    Note: These configuration variables are used as system environment variables within the Java sample code provided in this tutorial. However, you can modify the function code to use an alternative approach, such as the Fn RuntimeContext. For more information, see Using the Fn RuntimeContext with Functions.

    Secret Name/Key Value
    FN_AAA_KEY 123456
    FN_BBB_KEY 898989
    FN_ORACLE_KEY ABCD1234
  6. You can configure these settings through the OCI Console by navigating to Developer Services. Under Functions, click Applications, select your application, then select your function. In the function details page, click Configuration.

    configuration

    Or

    Run the fn commands.

    fn config function --help
    
    MANAGEMENT COMMAND
    fn config function - Store a configuration key for this function
    
    USAGE
    fn [global options] config function <app-name> <function-name> <key> <value>
    
    DESCRIPTION
    This command sets the configuration of a specific function for an application.
    
    fn config function chafikFunctions authorizationfunctionjava FN_ORACLE_KEY ABCD1234
    
  7. Run the following command to invoke the function.

    # Invoke the function to check if it's working as expected
    echo -n '{"data" : {"customer":"ORACLE", "token": "ABCD1234"}}' | fn invoke chafikFunctions authorizationfunctionjava
    

    Note: The initial invocation might take up to one minute to warm up the function. Review the configuration for any additional settings. For more information, see Reducing Initial Latency Using Provisioned Concurrency.

    Test with both valid and invalid data to verify the function responses.

    invoke function

Task 5: Create OCI API Gateway and a Mock API to use the Authorizer Function

Note: Make sure to select your public subnet.

  1. Go to the OCI Console, navigate to Developer Services, API Management, Gateways and click Create Gateway.

    create application

  2. Go to the Gateway details page and note down Hostname.

    gateway hostname

  3. Create a deployment in API gateway. In Basic information, enter the following information.

    • Path prefix: Enter /authFunction.

    Note: Hostname and Path prefix from API gateway will be used to form the API endpoint.

    basic Information

  4. In Authentication, enter the following information.

    • Select Single Authentication.

    • Select Authorizer Function.

    • Oracle Functions application: Select application created in Task 4.

    • Oracle Function: Select function created in Task 4.

    • Select Multi-argument authorizer function.

    • Function arguments: enter the following information.

      Context table Header name Argument name
      request.headers customer customer
      request.headers token token

    Note The Header name refers to the information included in the request header when invoking the API endpoint. The Argument name is the parameter name sent to the authorizer function, refer to the Java code in Task 4.3

    single authentication

    function arguments

  5. In Routes, create a single route for a mock test with the following information.

    • Path: Enter /mock.
    • Methods: Select GET.
    • Backend Option: Select Edit added single backend.
    • Backend Type: Select Stock response.

    route

  6. In Routes, define the Mock Response and click Next.

    • Status code: Enter 200.
    • Body: Enter {“mensagem” : “ok”}.
    • Header name: Select Content-Type.
    • Header Value: Select application/json; charset=UTF-8.

    mock

  7. In Review, verify the configuration and click Save Changes to complete the deployment creation.

  8. Run the curl command to test your API.

    # Invoke using <Verb Defined in Route> with the endpoint like: <API Gateway Hostname> + <Deployment Path Prefix> + <Route Path>
    # Send parameters, such as customer and token, in the Header with values configured in Task 4 - Step 5
    curl -i -H "customer: AAA" -H "token: 123456" -X GET https://yourapigatewayhosta.your-region.oci.customer-oci.com/authFunction/mock
    

    invoke function

    If invoking with invalid information, the response will be HTTP/1.1 401 Unauthorized.

    401 status

Task 6: Use OCI API Gateway to Retrieve Parameters and Scope from the Authorizer Functions

Note Refer to the Java code downloaded in Task 4. This task explains how to work with result.context and result.scope within the API gateway.

  1. Retrieve context values from the authorizer functions.

    context variable

    Consider a scenario where you need to retrieve information from the authorizer function and use it within the API gateway. For example, you might want to use an authorization token to invoke a backend service.

    Note: In this lab demonstration, the information is returned in the response header.

  2. Go to the OCI Console, navigate to Developer Services, API Management, Gateways and select your gateway. Click Deployments, select the deployment created in Task 5, and click Edit.

    edit deployment

  3. Navigate to Routes and click Show route response policies.

    route response

  4. In Response Policies, under Header transformations, click Add to proceed.

    add button

  5. In the Response header transformations page, configure your API gateway as shown in the following image and click Apply Changes.

    Both parameters from the Java code will be included on API response headers.

    • Header name: This field specifies the name of the header attribute in the API response.
    • Values: This field specifies the name of the attribute retrieved from the authorizer function.

    Use the following format:

    ${request.auth[attributeNameFromAuthorizerFunction]}
    
    #examples
    ${request.auth[valor01]}
    ${request.auth[valor02]}
    

    header setup

  6. Review your header response setup. Click Next to review the changes and click Save Changes to apply.

    check header setup

  7. Test the API and examine the response headers.

    header response

  8. Let us clarify how to use scope values from an authorizer function to enhance security.

    Note: In the context of authorization, scope refers to the specific permissions or access levels granted to a user or application.

    context variable

    The authorizer function returns all available scopes (in our example, this is hardcoded) for this API call.

    For some Routes in your API Gateway Deployment, you may want to allow only specific scopes to enhance security.

    Go to the OCI Console, navigate to Developer Services, API Management, Gateways, and select your gateway. Click Deployments, select the deployment created in Task 5, and click Edit.

    edit deployment

  9. Navigate to Routes and click Show route request policies.

    route request

  10. In Request Policies, under Authorization, click Edit.

    edit button

  11. In Authorization policy, select Any as Authorization type, add all Allowed Scope returned by the authorizer function, and click Apply Changes.

    authorization policy

  12. In Review, review your changes, click Next and then click Save Changes to apply your modifications.

    authorization policy

  13. Test the API and verify it is working. Scopes are returned by the authorizer function.

    test sucessed

  14. Change the API gateway to use a scope not returned by the authorizer function.

    Review your changes, click Next, and then Save Changes to apply your modifications.

    scope fail

  15. Test the API and verify the result.

    authorization policy

    The response will be a 404 Not Found http status.

    Check that the authorizer functions work correctly, as both headers are returned. However, the route backend fails due to scope authorization validation in the request policies.

Acknowledgments

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.