Calling HTTP pages from Plsql - oracle

I am trying to call a page from PLSQL
declare
httprequest UTL_HTTP.req;
httpresp UTL_HTTP.resp;
v_http_url VARCHAR2 (200) := 'http://localhost:38801/BatchMvcDriver/Index?ID=161';
begin
httprequest := UTL_HTTP.begin_request (url => v_http_url,
method => 'POST');
UTL_HTTP.set_header (httprequest,
'Content-Type',
'text/xml; charset=utf-8'
);
UTL_HTTP.set_header (httprequest, 'Content-Length', 64);
UTL_HTTP.write_line (httprequest, 'some string');
httpresp := UTL_HTTP.get_response (httprequest);
UTL_HTTP.end_request (httprequest);
UTL_HTTP.end_response (httpresp);
end;
It said
ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1130
ORA-24247: network access denied by access control list (ACL)
ORA-06512: at line 7
I tried to
begin
dbms_network_acl_admin.create_acl (
acl => 'utl_http.xml',
description => 'HTTP Access',
principal => 'SCOTT',
is_grant => TRUE,
privilege => 'connect',
start_date => null,
end_date => null
);
I am getting this error
ERROR at line 2:
ORA-06550: line 2, column 3:
PLS-00201: identifier 'DBMS_NETWORK_ACL_ADMIN' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored
How to get rid of this??

Related

If I create an ACL using sys as sysdba for APEX_210200 does the ACL apply to sys

Following this guide
https://oracle-base.com/articles/misc/azure-ad-authentication-for-oracle-apex-applications#add-web-credentials
So running this
l_username varchar2(30) := 'APEX_210200';
begin
dbms_network_acl_admin.append_host_ace(
host => 'login.microsoftonline.com',
lower_port => 443,
ace => xs$ace_type(privilege_list => xs$name_list('connect'),
principal_name => l_username,
principal_type => xs_acl.ptype_db));
And then I try to test it with
l_json CLOB;
BEGIN
apex_web_service.g_request_headers( 1 ).name := 'User-Agent';
apex_web_service.g_request_headers( 1 ).value := 'Application Express';
l_json := apex_web_service.make_rest_request(
p_url => 'login.microsoftonline.com',
p_http_method => 'GET'
);
DBMS_OUTPUT.put_line('l_clob=' || l_json);
END;
But I get
ORA-06512: at "APEX_210200.WWV_FLOW_WEB_SERVICES", line 1182
ORA-06512: at "APEX_210200.WWV_FLOW_WEB_SERVICES", line 782
ORA-24247: network access denied by access control list (ACL)
But the web credentials + Authentication Schemes does work from within the APEX APP itself (logging into Azure and returning to the app)
Does my test fail because I'm running as sys?

How to use the MEMBER_OF2 function in Oracle Apex using the APEX_LDAP package

Since I linked our Microsoft Active Directory with my Apex application using LDAP, I am trying to retrieve the groups for the user currently logged in from the Active Directory.
Here's the documentation: https://docs.oracle.com/cd/E59726_01/doc.50/e39149/apex_ldap.htm#AEAPI242
Here's my code of my dynamic action on page load, I am trying to retrieve a VARCHAR2 of all the groups the current user is part of, and to put it in a display-only field :
BEGIN
:P1_NEW := APEX_LDAP.MEMBER_OF2(
p_username => v('APP_USER'),
p_pass => 'mypassword',
p_auth_base => 'DOMAIN\',
p_host => 'XX.X.XXX.XX',
p_port => 389);
END;
But when I load my page, this error occurs
Ajax call returned server error ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 for Execute PL/SQL Code.
What's wrong in my code ? Thank you in advance for your help.
Thomas
I think you are using wrong the API Package APEX_LDAP. I am doing this on my own enviornment in a different way, but I am using Enterprise Edition:
Oracle Database version 19c
Oracle Apex version 20.1
Oracle Oracle Rest Data Services version 20.4
I have an authentication schema to make the login against the LDAP server of my own company. That authentication schema replaces the default one of Apex Locally managed users.
Application --> Shared Components --> Authentication Schemas --> Custom
function fn_val_user_pwd_ldap (
p_username in varchar2,
p_password in varchar2
)
return boolean
is
l_ldap_host varchar2(100) := 'myldaphost.com';
l_ldap_port number := 389 ;
begin
if APEX_LDAP.AUTHENTICATE(
p_username =>p_username,
p_password =>p_password,
p_search_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port)
then
dbms_application_info.set_action(null);
return true;
else
apex_util.set_authentication_result(p_code => 110);
apex_util.set_custom_auth_status(p_status => 'Username or password incorrect.');
dbms_application_info.set_action(null);
return false;
end if;
end;
Then, I have a post auth procedure in the same authentication method to retrieve the groups in LDAP. I prefer this way because it executes after the authentication, but you can do it also with a dynamic action.
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => ':APP_USER',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Mycompany,DC=de,DC=com,DC=corp',
p_host => 'myldaphost.com',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
We don't use SSL to communicate internally with the LDAP Server, as this application is intranet. So the parameter p_use_ssl is by default to N.
As I was telling you in the comment section of your own question, I think the parameter p_auth_base refers to the LDIF format of your own LDAP server, not the domain name that refers to the AD.
UPDATE
Let me show you how it works. ( Of course, I hide sensitive information of my own company ). Sometimes it might happen that you can't get the group information as null. I am not sure here whether is a LDAP authorization issue rather than a problem with the APEX package itself
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED ECHO ON
DECLARE
is_ok boolean;
l_mes varchar2(2000);
l_val varchar2(4000);
l_ldap_host varchar2(100) := 'myldapserver.com';
l_ldap_port number := 389 ;
BEGIN
if APEX_LDAP.AUTHENTICATE(
p_username =>'X329097',
p_password =>'********',
p_search_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port )
then
is_ok := true;
l_mes := 'Username and Password Correct' ;
dbms_output.put_line(l_mes);
else
l_mes := 'Username and Password Invalid' ;
dbms_output.put_line(l_mes);
end if;
if is_ok
then
l_val := APEX_LDAP.MEMBER_OF2(
p_username => 'X329097',
p_pass => '*********',
p_auth_base => 'OU=Users,OU=Mycompany,DC=****,DC=*****,DC=****,DC=corp',
p_host => l_ldap_host,
p_port => l_ldap_port);
dbms_output.put_line(l_val);
end if;
END;
/
Username and Password Correct
SC_APEX_ADMIN:SC_ORACLE_ADMIN
PL/SQL procedure successfully completed.
I tried to add your function and I cannot access to my application from my Login Page anymore. I've tried on the SQL Commands, here's what I got
DECLARE
VAL BOOLEAN;
BEGIN
IF APEX_LDAP.AUTHENTICATE(
p_username => 'thomas.tirole',
p_password => 'mypassword',
p_search_base => 'OU=Users,OU=Domain,DC=domain,DC=ch',
p_host => 'xx.x.xxx.xx',
p_port => 389
) THEN
dbms_output.put_line('AUTENTHICATED');
ELSE
DBMS_OUTPUT.PUT_LINE('NOT AUTHENTICATED');
END IF;
END;
---------------------------------------
NOT AUTHENTICATED
Statement processed.
0.00 seconds
If i try to do the MEMBER_OF2 function on the SQL Command, here's what I got :
declare
l_groups varchar2(4000);
BEGIN
l_groups := APEX_LDAP.MEMBER_OF2(
p_username => 'thomas.tirole',
p_pass => 'mypassword',
p_auth_base => 'OU=Users,OU=Domain,DC=domain,DC=ch', -- SAME WITH DOMAIN\
p_host => 'xx.x.xxx.xx',
p_port => 389);
htp.p('Is Member of:'||l_groups);
END;
---------------------------------------
ORA-31202: DBMS_LDAP : Erreur client/serveur LDAP : Invalid credentials. 80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 508
ORA-06512: à "SYS.DBMS_SYS_ERROR", ligne 86
ORA-06512: à "SYS.DBMS_LDAP", ligne 1487
ORA-06512: à "SYS.DBMS_LDAP", ligne 79
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 85
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 172
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 214
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 235
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 464
ORA-06512: à "APEX_210100.WWV_FLOW_LDAP", ligne 523
ORA-06512: à ligne 4
ORA-06512: à "SYS.DBMS_SQL", ligne 1721

Oracle Cloud > utl_http fails with a ORA-29273: HTTP request failed ORA-29024: Certificate validation failure ORA-06512

I am working with a temporary Oracle Cloud account. What I thought was identical functionality works on the Apex Web Service, but not with UTL_HTTP. So this snippet works and returns the issue we are looking for.
DECLARE
L_json_response varchar2(32767);
BEGIN
apex_web_service.g_request_headers(1).name := 'Content-Type';
apex_web_service.g_request_headers(1).Value := 'application/json';
L_json_response := apex_web_service.make_rest_request ( p_url =>
'https://mycompany.atlassian.net/rest/api/3/issue/BLABLA-23862', p_http_method => 'GET',
p_username => 'My.Username#mycompany', p_password => 'osBJWHhPasdffNVOQ5AA11D5'); -- Password is my Jira API Token
EXCEPTION WHEN OTHERS THEN raise_application_error(-20001,'An error was encountered -
'||SQLCODE||' -ERROR- '||SQLERRM);
END;
I can't use the Apex web service in the end product, and we need to use UTL_HTTP. This snippet should from my understanding do the same:
DECLARE
req utl_http.req;
res utl_http.resp;
url varchar2(4000) := 'https://mycompany.atlassian.net/rest/api/3/issue/BLABLA-23862';
buffer varchar2(4000);
BEGIN
req := utl_http.begin_request(url, 'GET');
utl_http.set_header(req, 'Content-Type', 'application/json');
utl_http.set_header(req, 'Authorization', 'Basic ' || utl_encode.base64_encode('my.msername#mycompany:osBJWHhPasdffNVOQ5AA11D5'));
res := utl_http.get_response(req);
utl_http.read_text(res, buffer);
END;
But returns:
ORA-29273: HTTP request failed
ORA-29024: Certificate validation failure
ORA-06512: at "SYS.UTL_HTTP", line 639
ORA-06512: at "SYS.UTL_HTTP", line 1415 ORA-06512...
The key is the UTL_HTTP.SET_WALLET('');. You need to set the wallet(with empty string parameter) before initial http request.
The following code snippet tested with in Oracle Cloud ATP (Autonomous Transition Processing) database:
Setup network ACL
BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(acl => 'my_acl.xml',
description => 'ACL for http request.',
principal => 'MY_USER',
is_grant => true,
privilege => 'connect');
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(acl => 'my_acl.xml',
principal => 'MY_USER',
is_grant => true,
privilege => 'resolve');
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(acl => 'my_acl.xml', host => 'www.oracle.com');
END;
Test https request
DECLARE
l_text VARCHAR2(32767);
BEGIN
UTL_HTTP.SET_WALLET('');
l_text := UTL_HTTP.REQUEST('https://www.oracle.com/index.html');
dbms_output.put_line(l_text);
END;
See official document and example (on the bottom of page):
In a way #OldProgrammer answered this the comment from 29-12-2020m but I don't know how to attribute the answer.
I needed to either couple the UTL_HTTP code to default wallet or create a new one. APEX_WEB_SERVICE probably does this implicitly while UTL_HTTP has to have it spelled out.
My question was for Oracle Cloud and I couldn't make the toolchain from OldProgrammers link work in Oracle Cloud. Rolled out a VM and it works.

Invalid ACL identifier

Im trying to make a REST API call from db and for that i have tried to create a ACL first.Below are the query,I tried to execute via sysdba user.Im getting error.
Can someone help me.
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (
acl => 'test_sx_acl_file.xml',
description => 'A test of the ACL functionality',
principal => 'node',
is_grant => TRUE,
privilege => 'connect',
start_date => SYSTIMESTAMP,
end_date => NULL);
end;
/
PL/SQL procedure successfully completed.
2)
BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl ( acl => 'test_sx_acl_file.xml ', host => '*.testapi.com', lower_port => NULL, upper_port => NULL);
END;
/
ERROR at line 1:
ORA-46059: Invalid ACL identifier specified
ORA-06512: at "SYS.DBMS_NETWORK_ACL_ADMIN", line 70
ORA-06512: at "SYS.DBMS_NETWORK_ACL_ADMIN", line 484
ORA-06512: at line 2
Why is that? what could be the reason

Oracle Invoke REST Service from pl/sql

I need help with this code, I am getting an error saying following.
ORA-29273: HTTP request failed
ORA-12541: TNS:no listener
ORA-06512: at "SYS.UTL_HTTP", line 368
ORA-06512: at "SYS.UTL_HTTP", line 1118
ORA-06512: at line 5
29273. 00000 - "HTTP request failed"
*Cause: The UTL_HTTP package failed to execute the HTTP request.
*Action: Use get_detailed_sqlerrm to check the detailed error message.
Fix the error and retry the HTTP request.
I contacted network team and they see bidirectional traffic on that port being done, so I am not sure what else is/could be wrong? any ideas?
create or replace
procedure Test_Rest_Call3
is
req utl_http.req;
res utl_http.resp;
url varchar2(4000) := 'http://ipaddresshere:9099/api/batchProcess/1';
name varchar2(4000);
buffer varchar2(4000);
content varchar2(4000) := '';
begin
req := utl_http.begin_request(url, 'DELETE',' HTTP/1.1');
utl_http.set_header(req, 'user-agent', 'mozilla/4.0');
utl_http.set_header(req, 'content-type', 'application/json');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
-- process the response from the HTTP call
begin
loop
utl_http.read_line(res, buffer);
dbms_output.put_line(buffer);
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body
then
utl_http.end_response(res);
end;
end Test_Rest_Call3;
Have you checked if DBA granted to execute utl_http?
Just try to run it to be sure:
select utl_http.request('http://ipaddresshere:9099/api/batchProcess/1') from dual;
If you get error then ask DBA to give the permission accordingly:
grant execute on utl_http to your_oracle_user_name
grant execute on dbms_lock to user_name
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (
acl => 'local_sx_acl_file.xml',
description => 'A test of the ACL functionality',
principal => 'put your user_name',
is_grant => TRUE,
privilege => 'connect',
start_date => SYSTIMESTAMP,
end_date => NULL);
end;
begin
DBMS_NETWORK_ACL_ADMIN.assign_acl (
acl => 'local_sx_acl_file.xml',
host => 'localhost',
lower_port => 9002,
upper_port => NULL);
end;
I hope it will help.
Cheers,
Morteza Fakoorrad

Resources