8i | 9i | 10g | 11g | 12c | 13c | 18c | 19c | 21c | 23ai | Misc | PL/SQL | SQL | RAC | WebLogic | Linux
Oracle REST Data Services (ORDS) : Allowed Origins
This article gives an example of controlling the allowed origins for a web service created with Oracle REST Data Services (ORDS).
- Assumptions and Comments
- Create a Test Database User
- Enable ORDS and Create Web Service
- Setting Allowed Origins
Related articles.
Assumptions and Comments
This article assumes the following.
- You already have a functioning installation of ORDS on a supported database.
- You have a way to call the web services. GET web services can be called from a browser,
curl
or a REST client.
Create a Test Database User
Create a test user.
conn sys/SysPassword1@//localhost:1521/pdb1 as sysdba --drop user testuser1 cascade; create user testuser1 identified by testuser1 default tablespace users quota unlimited on users; grant create session, create table to testuser1;
Create and populate a copy of the EMP table in the test user.
conn testuser1/testuser1@//localhost:1521/pdb1 -- drop table emp purge; create table emp ( empno number(4,0), ename varchar2(10 byte), job varchar2(9 byte), mgr number(4,0), hiredate date, sal number(7,2), comm number(7,2), deptno number(2,0), constraint pk_emp primary key (empno) ); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7369,'SMITH','CLERK',7902,to_date('17-DEC-80','DD-MON-RR'),800,null,20); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7499,'ALLEN','SALESMAN',7698,to_date('20-FEB-81','DD-MON-RR'),1600,300,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7521,'WARD','SALESMAN',7698,to_date('22-FEB-81','DD-MON-RR'),1250,500,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7566,'JONES','MANAGER',7839,to_date('02-APR-81','DD-MON-RR'),2975,null,20); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7654,'MARTIN','SALESMAN',7698,to_date('28-SEP-81','DD-MON-RR'),1250,1400,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7698,'BLAKE','MANAGER',7839,to_date('01-MAY-81','DD-MON-RR'),2850,null,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7782,'CLARK','MANAGER',7839,to_date('09-JUN-81','DD-MON-RR'),2450,null,10); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7788,'SCOTT','ANALYST',7566,to_date('19-APR-87','DD-MON-RR'),3000,null,20); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7839,'KING','PRESIDENT',null,to_date('17-NOV-81','DD-MON-RR'),5000,null,10); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7844,'TURNER','SALESMAN',7698,to_date('08-SEP-81','DD-MON-RR'),1500,0,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7876,'ADAMS','CLERK',7788,to_date('23-MAY-87','DD-MON-RR'),1100,null,20); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7900,'JAMES','CLERK',7698,to_date('03-DEC-81','DD-MON-RR'),950,null,30); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7902,'FORD','ANALYST',7566,to_date('03-DEC-81','DD-MON-RR'),3000,null,20); insert into emp (empno,ename,job,mgr,hiredate,sal,comm,deptno) values (7934,'MILLER','CLERK',7782,to_date('23-JAN-82','DD-MON-RR'),1300,null,10); commit;
Enable ORDS and Create Web Service
Enable REST web services for the test schema. We use any unique and legal URL mapping pattern for the schema, so we don't expose the schema name. In this case we use "hr" as the schema alias.
conn testuser1/testuser1@//localhost:1521/pdb1 begin ords.enable_schema( p_enabled => true, p_schema => 'TESTUSER1', p_url_mapping_type => 'BASE_PATH', p_url_mapping_pattern => 'hr', p_auto_rest_auth => false ); commit; end; /
Web services from the schema can now be referenced using the following base URLs.
http://localhost:8080/ords/hr/ https://localhost:8443/ords/hr/
We create a web service for the EMP table. The web service returns the details of a specific employee based on their employee number.
BEGIN ORDS.define_service( p_module_name => 'rest-v1', p_base_path => 'rest-v1/', p_pattern => 'employees/:empno', p_method => 'GET', p_source_type => ORDS.source_type_collection_feed, p_source => 'SELECT * FROM emp WHERE empno = :empno', p_items_per_page => 0); COMMIT; END; /
The following URLs are valid for the current installation.
http://localhost:8080/ords/hr/rest-v1/employees/7499 https://localhost:8443/ords/hr/rest-v1/employees/7499
We are now ready to start.
Setting Allowed Origins
We start by testing the two URLs listed above. We use the "-k" flag for the HTTPS call as we are using a self-signed certificate, and we don't want to have a certificate failure on the call. In both cases the employee details are returned.
$ curl http://localhost:8080/ords/hr/rest-v1/employees/7499 {"items":[{"empno":7499,"ename":"ALLEN","job":"SALESMAN","mgr":7698,"hiredate":"1981-02-20T00:00:00Z", "sal":1600,"comm":300,"deptno":30}],"hasMore":false,"limit":0,"offset":0,"count":1, "links":[{"rel":"self","href":"http://localhost:8080/ords/hr/rest-v1/employees/7499"}, {"rel":"describedby","href":"http://localhost:8080/ords/hr/metadata-catalog/rest-v1/employees/item"}]} $ $ curl -k https://localhost:8443/ords/hr/rest-v1/employees/7499 {"items":[{"empno":7499,"ename":"ALLEN","job":"SALESMAN","mgr":7698,"hiredate":"1981-02-20T00:00:00Z", "sal":1600,"comm":300,"deptno":30}],"hasMore":false,"limit":0,"offset":0,"count":1, "links":[{"rel":"self","href":"https://localhost:8443/ords/hr/rest-v1/employees/7499"}, {"rel":"describedby","href":"https://localhost:8443/ords/hr/metadata-catalog/rest-v1/employees/item"}]} $
In this example we set the "Origin" header to "https://example.com", and the employee details are returned.
$ curl -H "Access-Control-Request-Method: GET" \ -H "Origin: https://example.com" \ http://localhost:8080/ords/hr/rest-v1/employees/7499 {"items":[{"empno":7499,"ename":"ALLEN","job":"SALESMAN","mgr":7698,"hiredate":"1981-02-20T00:00:00Z", "sal":1600,"comm":300,"deptno":30}],"hasMore":false,"limit":0,"offset":0,"count":1, "links":[{"rel":"self","href":"http://localhost:8080/ords/hr/rest-v1/employees/7499"}, {"rel":"describedby","href":"http://localhost:8080/ords/hr/metadata-catalog/rest-v1/employees/item"}]} $
We use the SET_MODULE_ORIGINS_ALLOWED
procedure in the ORDS
package to set the allowed origins for the module containing the the web service call. Notice we have not included "https://example.com" in the list of allowed origins.
begin ords.set_module_origins_allowed( p_module_name => 'rest-v1', p_origins_allowed => 'http://localhost,https://localhost'); commit; end; /
We repeat the previous call with the "Origin" header set to "https://example.com", and we get a Cross Origin Sharing (CORS) error.
$ curl -H "Access-Control-Request-Method: GET" \ -H "Origin: https://example.com" \ http://localhost:8080/ords/hr/rest-v1/employees/7499 { "code": "Forbidden", "title": "Forbidden", "message": "The request cannot be processed because it failed cross origin request validation ", "o:errorCode": "ORDS-13002", "cause": "This resource does not support Cross Origin Sharing requests, or the request Origin is not authorized to access this resource. ", "action": "If ords is being reverse proxied ensure the front end server is propagating the host name, scheme and port correctly. If using mod_proxy ensure ProxyPreserveHost is set to On. If using SAML with Oracle APEX, ensure security.externalSessionTrustedOrigins is correctly configured. If using a RESTful Service ensure the Origins Allowed value is correctly configured", "type": "tag:oracle.com,2020:error/Forbidden", "instance": "tag:oracle.com,2020:ecid/A-UFKJDzri_u1m6mBgJgVA" } $
We add "example.com" to the allowed origins.
begin ords.set_module_origins_allowed( p_module_name => 'rest-v1', p_origins_allowed => 'http://localhost,https://localhost,http://example.com,https://example.com'); commit; end; /
Now the call with the "Origin" header set to "https://exmaple.com" works.
$ curl -H "Access-Control-Request-Method: GET" \ -H "Origin: https://example.com" \ http://localhost:8080/ords/hr/rest-v1/employees/7499 {"items":[{"empno":7499,"ename":"ALLEN","job":"SALESMAN","mgr":7698,"hiredate":"1981-02-20T00:00:00Z", "sal":1600,"comm":300,"deptno":30}],"hasMore":false,"limit":0,"offset":0,"count":1, "links":[{"rel":"self","href":"http://localhost:8080/ords/hr/rest-v1/employees/7499"}, {"rel":"describedby","href":"http://localhost:8080/ords/hr/metadata-catalog/rest-v1/employees/item"}]} $
We can unset the allowed origins list by passing in a NULL or an empty string.
begin ords.set_module_origins_allowed( p_module_name => 'rest-v1', p_origins_allowed => ''); commit; end; /
For more information see:
Hope this helps. Regards Tim...