Part 1: Securing your REST API
Some time ago we created a simple REST API using APEX RESTful Services to serve us for some reports. I wouldn’t go into details on how to create such, as there are many sources out there describing how to create a REST service in APEX. You could take a look at this Workshop by Oracle Labs if you just get started. I will focus on the process of securing it in this blog post.
By default the modules (APIs) you create using the APEX interface are not secured. If you have a GET handler method for example, you could see the JSON result by simply copy/pasting the URL in your browser without any authorization.
But of course, when this is a publicly available URL and it holds some sensitive information you wouldn’t want to leave it accessible for everyone. In addition to that you might have a number of partners that should have access to different APIs and different methods, and they should be able to authorize with their own credentials securely.
Module (API)– the REST enabled service we want to protect
Role– it will be associated the
Clientwe create later and is used to make access distribution to different modules easier
Privilege– the main object that defines the module security. It links the
Client– an object that is granted some access to a module, using the already created
Privilege. The Client has two main properties:
Client ID– similar to a username that is used for authentication.
Client Secret– similar to a password for a username. It always goes hand by hand with the Client Id.
Token– generated when a correct Client Id and Client Secret are passed to ORDS. The Token is then used as a header is the HTTP request and authorizes you for accessing the API
Ways to Authenticate
ORDS provides two built-in ways to authenticate your API calls:
- Basic Authentication – using Username and Password
- OAuth2 – using a Client credentials (Client ID and Client Secret)
The other way to authenticate is using a third-party provider, such as OKTA, Azure, etc. It offloads all of the efforts to issue, renew, revoke credentials and is a preffered method in enterprise solutions.
- You need to create a user/password pair. You have two options to do it:
- Using a
Database Userand a
CREATE USER api_user IDENTIFIED BY api_user_pass; GRANT CREATE SESSION TO api_user; CREATE ROLE customer_api_role; GRANT customer_api_role TO api_user;
- or using an
- Create a new APEX Group, named
- Create a new APEX User, named
api_userand add it to the
- Create a new APEX Group, named
- Create a Role and Privilege using the ORDS RESTful Services
- In APEX, go to
- Click on
Create Rolebutton and enter customer_api_role as a Role Name
The same could be done using the ORDS package:
begin ORDS.create_role( p_role_name => 'customer_api_role' ); end;
- Go to
Privilegesand click on
Create Privilegebutton. Enter customer_api_priv as a Name, select customer_api_role from the list of roles that you want to associate with that privilege and select the module you want to secure in Protected Modules section.
The same could be done using the ORDS package (Full documentation of the package – in the ORDS Reference):
begin ORDS.create_privilege( p_name => 'customer_api_priv', p_role_name => 'customer_api_role', p_label => 'Test Privilege', p_description => 'A test privilege created using PL/SQL.'); ORDS.create_privilege_mapping( p_privilege_name => 'customer_api_priv', p_pattern => '/customer/*'); commit; end;
It is very important that you name your Database Role or your APEX Group with exactly the same name as your ORDS Role – in our example it’s customer_api_role. This will allow ORDS to map the ORDS REST service Role correctly.
- First step is to create an ORDS Role and Privilege, following the steps above – either using the APEX interface or manually by using the ORDS package.
- Second step is to create Client credentials. There is no user interface in APEX that allows you to do that, but it is possible using a simple call to the AUTH package.
begin OAUTH.create_client( p_name => 'big_partner_company', p_grant_type => 'client_credentials', p_owner => 'My company name', p_description => 'A client for API integrations by the Big Partner Company', p_support_email => 'email@example.com', p_privilege_names => 'customer_api_priv' ); OAUTH.grant_client_role( p_client_name => 'big_partner_company', p_role_name => 'customer_api_role' ); commit; end;
That step includes also a mapping of our newly created Client credentials to the ORDS Role that we created earlier.
Full documentation of this package could be found in the OAUTH Reference
- Now you should already have the Client credentials created. To see them, use the following query:
SELECT id, name, auth_flow, response_type, client_id, client_secret FROM USER_ORDS_CLIENTS;
What you need are the Client_Id and Client_Secret.
- The URL where ORDS will issue a token, based on a correct Client_Id and Client_Secret. It always follows this pattern:
Well done! Following these steps you now have secured your REST API.
In Part 2, see some different methods of accessing your secured API, including curl, postman and PL/SQL.
– OAUTH API reference
– ORDS API reference
– APEX_WEB_SERVICE API reference
– Blog posts:
3 thoughts on “ORDS, APEX and secure REST APIs (Part 1 – secure the API)”
Very good post, thank you very much! About using a third-party provider, could you make a “part 3” post explaning more about how to use ORDS that way? Thanks again!