8i | 9i | 10g | 11g | 12c | 13c | 18c | 19c | 21c | 23c | Misc | PL/SQL | SQL | RAC | WebLogic | Linux

Home » Articles » Misc » Here

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).

Related articles.

Assumptions and Comments

This article assumes the following.

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...

Back to the Top.