APEX_WEB_SERVICE Simplifies Oauth2.0 Web Services

In OAuth 2.0 client credentials, acquiring a token necessitates passing the client ID and client secret. Upon successful validation, a token is returned, which is then utilized to access other secured web services. This token remains valid for multiple calls to web services until its expiration.

One method of calling web services involves using UTL_HTTP, typically employed by developers on Oracle databases that does not have Oracle Apex installed. However, this approach presents several disadvantages:

  • A need arises to develop an additional mechanism for storing and retrieving credentials. These credentials are stored in an unencrypted table, raising significant security concerns.
  • Manual management of token expiration becomes necessary, requiring awareness of its expiry to fetch a new token.
  • Performance is impacted; in the provided example, each call to the web service generates a new token instead of reusing the existing one until its expiration.
Using UTL_HTTP
				
					declare   
    CURSOR get_cred IS
    select lookup_code, meaning 
	  from eba_apex_lookups  
    where lookup_type like '%APEX_CRED%'
      and enabled_flag = 'Y'; 
	  
    v_req            UTL_HTTP.req;
    v_resp           UTL_HTTP.resp;
    v_txt            VARCHAR2 (5000);
    v_access_token   VARCHAR2 (5000);
    v_url            VARCHAR2 (1024);
    auth_body        VARCHAR2 (4000);
    g_wallet         varchar2(100);
    g_wallet_pwd     varchar2(100);

BEGIN
    
	-- Get credentials
    FOR x IN get_cred LOOP
       IF x.lookup_code = 'TOKEN_URL' THEN
          v_url := x.meaning;
       ELSIF x.lookup_code = 'AUTH_BODY' THEN
          auth_body := x.meaning;
       ELSIF x.lookup_code = 'WALLET' THEN
          g_wallet := x.meaning;
       ELSIF x.lookup_code = 'WALLET_PWD' THEN
          g_wallet_pwd := x.meaning;
       END IF;
    END LOOP;
    
	-- Generate Token
    UTL_HTTP.set_wallet (g_wallet, g_wallet_pwd);
    v_req := UTL_HTTP.begin_request (v_url, 'POST', ' HTTP/1.1');
    UTL_HTTP.set_body_charset('UTF-8');
    UTL_HTTP.set_header (v_req,
                         'Content-Type',
                         'application/x-www-form-urlencoded');
    UTL_HTTP.set_header (v_req, 'Content-Length', LENGTH (auth_body));
    UTL_HTTP.write_text (v_req, auth_body);
    v_resp := UTL_HTTP.get_response (v_req);

    UTL_HTTP.read_line (v_resp, v_txt);
	-- Get Access Token
    SELECT JSON_VALUE (v_txt, '$.access_token')
      INTO v_access_token
      FROM DUAL;
    UTL_HTTP.end_response (v_resp);
    
    	
	IF length(v_access_token) > 1 THEN
	   -- Call Rest API
       v_url := 'https://graph.microsoft.com/v1.0/users/' || v_upn;;
       v_req := UTL_HTTP.begin_request (v_url, 'GET', ' HTTP/1.1');
       UTL_HTTP.set_body_charset('UTF-8');
       UTL_HTTP.set_header(v_req, 'Authorization', v_access_token);
       v_resp := UTL_HTTP.get_response (v_req);
	   -- read response	   
       UTL_HTTP.read_line (v_resp, v_txt);
       dbms_output.put_line ('response ' || v_txt);  
	END IF;
 EXCEPTION
   WHEN UTL_HTTP.end_of_body THEN
      UTL_HTTP.end_response (v_resp);
      IF v_resp.status_code < 200 OR v_resp.status_code >= 300 THEN
         dbms_output.put_line('Error Occurred');
      END IF;
END;    
				
			

 

The use of the ‘Web Credentials’ from Oracle Apex and APEX_WEB_SERVICE solves the pain points of using the UTL_HTP. Developers does not have to deal with calling the token and managing the token expiration. This is facilitated by passing the parameters p_credential_static_id and p_token_url to APEX_WEB_SERVICE, referencing the ‘Web Credentials’ and URL token, thereby streamlining the process. Additionally, ‘Web Credentials’ stored the client secret on encrypted.

Web Credentials

Using APEX_WEB_SERVICE
				
					DECLARE
  l_response_clob         CLOB;
  l_rest_url              VARCHAR2(1000);
  l_token_url             VARCHAR2(1000);
  l_count_posted          PLS_INTEGER;
  v_upn         VARCHAR2(100) := '<userPrincipalName>'; 
BEGIN
  -- To use Web Credentials, you need to create apex session
  apex_session.create_session (p_app_id => 100, p_page_id  => 1, p_username => 'ORCLAPEX');

  -- Set the URL of the REST Service.
  l_rest_url  := 'https://graph.microsoft.com/v1.0/users/' || v_upn;
  l_token_url := 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
  
  -- Call the web services passing the two parameters. 
  -- p_credential_static_id references the "MS_GRAPH_API_ACCESS" that was set up Workspace Utilities.
  -- p_token_url is token url for the l_rest_url
  l_response_clob := apex_web_service.make_rest_request(
     p_url                  => l_rest_url,
     p_http_method          => 'GET',
     p_credential_static_id => 'MS_GRAPH_API_ACCESS',
     p_token_url            => l_token_url);

  IF apex_web_service.g_status_code = 200 THEN
    -- 4. Check the response => l_response_clob, p_strict => true);
  END IF;
END;
/
				
			

Please note before you can call the web services you have to make sure the ACL and certificates are already set up. Click here for assistance in setting them up.