This post is part of a series that starts with this post.
In the last post we made the service secure beyond all recognition (sebar 🙂 ) or maybe better expressed as so secure that nobody has access. In this post we’ll look at how to set up access to it to allow just those we have given credentials to to have access.
To access a protected service one need to use a client-definition. id + secret, pretty much like how userid + password works, to get a token. That token is then what is supplied in every call. The client is then connected to the role we set up to protect the service. Thus, the “client” gives us access to the things the role protects.
Let’s set it up and test how it works.
We start with creating the client. We define the name and Oracle decides on id + secret. This setup is also made in the schema that created the service, rest_demo.
begin
oauth.create_client(
p_name => 'gnome_client',
p_grant_type => 'client_credentials',
p_description => 'A client to test security with.',
p_support_email => 'me@mydomain.com',
p_privilege_names => 'gnome_priv'
);
commit;
end;
/
Next, we connect the client we just created to the role we set up for the service.
begin
oauth.grant_client_role(
p_client_name => 'gnome_client',
p_role_name => 'gnome_role'
);
commit;
end;
/
That is it, now we just need to look up the credential we need to use to get a token to access the service with.
select name
, client_id
, client_secret
from user_ords_clients;
NAME CLIENT_ID CLIENT_SECRET gnome_client JQ6xxxxxV5_8X5xxxxxxBg.. LtxxxxxxgX_Cuxxxw..
That is my result, yours will differ slightly in the values of client_id and client_secret. The above values are of course not the actual ones I got.
To use the access to the service we first need to make one call to get a token before we can make a call to the service. We’re using cURL to demonstrate.
curl --user JQ6xxxxxV5_8X5xxxxxxBg..:LtxxxxxxgX_Cuxxxw.. --data "grant_type=client_credentials" https://.../ords/rest_demo_schema/oauth/token
{"access_token":"vpxxxxi5_izxxxxxxxxxOQ","token_type":"bearer","expires_in":3600}
A restenabled schema has always it’s token-server at …/<schema alias>/oauth/token. by sending in our credentials to it we get a token back that we can use to access secured services. The credential is the client-id and client-secret with a comma as de delimiter.
The answer tells us we have a token of the type bearer that will be valid for one hour.
Let’s use it to get access the the secured service.
curl -H"Authorization: Bearer vpxxxxi5_izxxxxxxxxxOQ" https://.../ords/rest_demo_schema/vw_rest_svc/
With that we get the response we’ve gotten used to with items and links and so forth. Remove the -H”…” and it is still a 401 – unauthorized access.
We now have the service secured and only those that know the client-id and client-secret can gain access to a token that allows access.
Doing the same in PL/SQL is just as easy. Let’s first remind ourselves of the PL/SQL we used with the unsecure service. It looked like this.
set serveroutput on
declare
payload clob;
begin
payload := apex_web_service.make_rest_request
(
p_url => 'https://.../ords/rest_demo_schema/vw_rest_svc/'
, p_http_method => 'GET'
);
dbms_output.put_line(payload);
end;
/
It will no longer do as the service will now return a 401. We need to gain access to it just like how we did in cURL.
declare
payload clob;
token_rec apex_web_service.oauth_token;
begin
apex_web_service.oauth_authenticate
( p_token_url => 'https://.../ords/rest_demo_schema/oauth/token'
, p_client_id => 'JQxxxxxxV5_8XxxxxxxxxBg..'
, p_client_secret => 'LtxxxxxxxxxxxgX_Cxxxxxxw..');
token_rec := apex_web_service.g_oauth_token;
apex_web_service.set_request_headers( p_name_01 => 'Authorization'
, p_value_01 => 'Bearer ' || token_rec.token);
payload := apex_web_service.make_rest_request
(
p_url => 'https://.../ords/rest_demo_schema/vw_rest_svc/'
, p_http_method => 'GET'
);
dbms_output.put_line(payload);
end;
/
Now we get the raw json back as we did before. Managing that, converting to columns and so forth now works the same exact way as all of that is just handling of JSON and as we have received the response it can now be dealt with as we did before.
That completes the series on going from a basic restenabled view to a secured REST-service. The one remaining thing to look at is a simple alternative to creating a view to restenable. That will be the content in the next and last post in this series.