It’s easier to run things unsecured.
It’s unconscionable to run things unsecured.
DON’T BE THIS GUY.
So Let’s Secure My Database and my Web Services
So I have a collection of REST enabled objects (tables, view, and procedures) and a SLEW of RESTful Service modules. I want ALL of them locked down.
So I need to create a Role and Privilege. And then I need to assign that privilege to what I want protected. Without said privilege, my user doesn’t get to use it (Authorized) even if I know who they are (Authenticated.)
I can do this GUI for PL/SQL, I’m going to show both.
The code:
BEGIN
ORDS.CREATE_ROLE(p_role_name => 'storyteller');
l_roles(1) := 'SQL Developer';
l_roles(2) := 'storyteller';
l_modules(1) := 'Banking';
l_modules(2) := 'abstract';
l_modules(3) := 'blind_body';
l_modules(4) := 'bool';
l_modules(5) := 'employee';
l_modules(6) := 'forums';
l_modules(7) := 'george';
l_modules(8) := 'norway';
l_modules(9) := 'otn';
l_modules(10) := 'package';
l_modules(11) := 'parameters';
l_modules(12) := 'performance';
l_modules(13) := 'plsql_table';
l_modules(14) := 'resources';
l_modules(15) := 'rpc';
l_modules(16) := 'sample_module';
l_modules(17) := 'simple';
l_modules(18) := 'test';
l_modules(19) := 'test2';
l_modules(20) := 'test3';
l_modules(21) := 'test4';
l_modules(22) := 'youtube';
l_patterns(1):= '/*';
ORDS.DEFINE_PRIVILEGE(
p_privilege_name => 'oracle.jeff.demo',
p_roles => l_roles,
p_patterns => l_patterns,
p_modules => l_modules,
p_label => '',
p_description => 'just something i made for giggles',
p_comments => NULL);
COMMIT;
END;
/
This looks like this in the GUI:
So I’ve manually listed modules to be protected – THIS IS THE HARD WAY.
What happens when I add a new module tomorrow, and I forget to update the priv?
Or what about all those REST enabled TABLEs and PL/SQL objects I’ve been working on?
Do THIS Instead
Let’s protect the URI pattern.
We are in the HR REST enabled Schema – so I can say starting from /hr/ (or whatever your schema alias is), protect these patterns that match. SO by putting /* – that ANTYHING after /ords/hr
No Go
Let’s make the call sans credentials.
Now with the ‘keys.’
So let’s go back to our PL/SQL code bit for defining the privilege:
l_patterns(1):= '/*';
This protects EVERYTHING under the schema where the privilege is defined. It doesn’t hurt to ‘double protect’ the modules by explicitly adding them, but there’s no need either.
The USER and the Role
This is an ORDS user, and I created it the normal way. The credentials are stored in an xml file under the ORDS configdir, and you’ll be using BASIC AUTH to authenticate. It’s not recommended in general, but it’s useful for demoing users and roles.
c:\ORDS\18.2>java -jar ords.war user ords_dev "storyteller" Enter a password for user ords_dev: Confirm password for user ords_dev: Oct 04, 2018 10:52:05 AM oracle.dbtools.standalone.ModifyUser execute INFO: Created user: ords_dev in file: c:\ords\config\ords\credentials
The REST Client I’m Using Today
A co-worker did a a demo playing with our new DB API (coming soon, stay tuned!), and they used this thing called Insomnia. I’ve been using it for two days, and so far, it’s great. They’re even on Twitter if you’re so obliged.
6 Comments
Hi Jeff,
I followed the manual as is and I am receiving 403 Forbiden.
Even the 401 error that is described at the manual I coudn’t achieve. I am only getting 403.
Any idea?
Manual: https://oracle-base.com/articles/misc/oracle-rest-data-services-ords-authentication
That’s not the manual, that’s Tim’s blog.
Please share what you’ve done, step by step, on the forums.
The manuals are here
https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/22.3/index.html
I still have difficulty understanding how to “map” a user/client identity to a defined ORDS role. Setting OAuth aside: as I understand it, standard HTTP daemons will populate AUTHENTICATED_USER environment variable and then pass that to the application (in this case ORDS), so I guess I am expecting a way to let ORDS know what values of AUTHENTICATED_USER should be mapped to a particular ORDS role. I feel like maybe I’m confusing a couple of different concepts here.
when the webserver passes over the authenticated user, it’s also passing over their roles…those roles needs to match up with the roles defined in ords
Thanks, Jeff. I think I understand better now. I think for most practical purposes, an SPNEGO/SSO setup is going to be mutually exclusive with an OAUTH2 setup. I.e., it would will probably be easier and more reliable to have SPNEGO/SSO authentication /not/ apply to the RESTful services parts of ORDS, but then not have to worry about dealing with roles (outside of the built-in role management stuff).
Hi Jeff.
I have a doubth using patterns in proivileges.
Are URL parameters supported on patterns for privileges?
I have this service
/posts/:id/tags
And i want to portect only /tags endpoint
I’ve tried following patterns but do not seem to work:
/posts/:id/tags
/posts/*/tags
What is the pattern needed to protect just /posts/:id/tags endpoint?