Recently on ODTUG mailing list one fellow asked about using custom authentication schemes in APEX. i thought it would be good idea for my blog post :)
In this video i will demonstrate how to create login page which authenticates username and passwords from database tables in Oracle APEX.
Note: The purpose of this post is just to show the setting up custom authentication therefore i have used a very simple db table with passwords stored as text.
In real world this password approach in not recommended you must store passwords in encrypted columns or use any procedure to convert passwords into encrypted form.
Database structure
create table my_users
(user_name varchar2(10),
user_pwd varchar2(10));
insert into my_users
values('Tom','Secret');
insert into my_users
values('Baig','oracle');
commit;
Authentication Function
create or replace function validate_user_from_db (p_username in varchar2, p_password in varchar2) return boolean as v_pw_check varchar2(1); begin select 'x' into v_pw_check from my_users where upper(user_name) = upper(p_username) and user_pwd = p_password; apex_util.set_authentication_result(0); return true; exception when no_data_found then apex_util.set_authentication_result(4); return false; end validate_user_from_db;
Authentication messages
0: Normal, successful authentication 1: Unknown User Name 2: Account Locked 3: Account Expired 4: Incorrect Password 5: Password First Use 6: Maximum Login Attempts Exceeded 7: Unknown Internal Error
A little code to test our authentication function( This function for only test in SQL prompt)
declare
vresult varchar2(10);
begin
if validate_user_from_db ('baig','oracle') then
dbms_output.put_line('OK');
else
dbms_output.put_line('ERROR');
end if;
end;
And finally a video tutorial steps
Happy learning,
Zeeshan Baig
You have a SERIOUS flaw in your functionality. YOU NEVER store a password in plain text, this is a BIG security no-no..... Also, if this is to be used in APEX, DBMS_OUTPUT is useless, you need to use a htp.p function call...
ReplyDeleteHow much development HAVE you done in APEX again??
Hi APEX developer,
ReplyDeleteThanks for comments. i have posted a update note on this blog post.
"Note: The purpose of this post is just to show the setting up custom authentication therefore i have used a very simple db table with passwords stored as text.
In real world this password approach in not recommended you must store passwords in encrypted columns or use any procedure to convert passwords into encrypted form."
Thanks dude!
ReplyDeleteI have followed this tutorial all the way through with a couple of changes for password encryption. I keep getting the error "PLS-00201: identifier 'APEX_UTIL.SET_AUTHENTICATION_RESULT' must be declared"
ReplyDeleteCan you help?
Great! Many thanks, it was that I need.
ReplyDeleteand how to do that with encripted text?
ReplyDeletethanks
Hi,
DeleteThere are many ways check the following links
http://www.oracle-base.com/articles/9i/storing-passwords-in-the-database-9i.php
http://www.oracle-base.com/articles/10g/transparent-data-encryption-10gr2.php
http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/d_crypto.htm
Hope it helps,
ZB
ORA-06550: line 4, column 5:
ReplyDeletePLS-00905: object GB_7133_S11_PLSQL.VALIDATE_USER_FROM_DB is invalid
ORA-06550: line 4, column 2:
PL/SQL: Statement ignored
2. vresult varchar2(10);
3. begin
4. if validate_user_from_db ('baig','oracle') then
5. dbms_output.put_line('OK');
6. else
i got this error
Please check that procedure is proper compiled.
DeleteZ
this is the function i am using
ReplyDeletecreate or replace function
validate_user_from_db(p_username in varchar2,p_password in varchar2)
return boolean
is
v_pw_check varchar2(1);
begin
select name
into v_pw_check
from customers
where upper(NAME)=upper(p_username)
and PASSWORD=p_password;
apex_util.set_authentication_result(0);
return true;
exception when no_data_found then
apex_util.set_authentication_result(4);
return false;
end validate_user_from_db;
--
when I executed that function it shows function processed ..
--
when i run below code ..
declare vresult varchar2(10);
begin
if validate_user_from_db ('Robin','vbc')
then dbms_output.put_line('ok');
else
dbms_output.put_line('ERROR');
end if;
end;
--
comes up with this error
ORA-06550: line 4, column 5:
PLS-00905: object GB_7133_S11_PLSQL.VALIDATE_USER_FROM_DB is invalid
ORA-06550: line 4, column 2:
PL/SQL: Statement ignored
2. vresult varchar2(10);
3. begin
4. if validate_user_from_db ('baig','oracle') then
5. dbms_output.put_line('OK');
6. else
--
here object is workspace name how to rectify this..
Hi,
DeleteYour earlier issue was PLS error now you said it says Function processed...So what is actual issue ? What is displays when you execute it? Have to tried to execute in SQL developer ?
Zeeshan
i tried to execute below code in sql developer
ReplyDeletedeclare vresult varchar2(10);
begin
if validate_user_from_db ('Robin','vbc')
then dbms_output.put_line('ok');
else
dbms_output.put_line('ERROR');
end if;
end;
but raises that error object invalid..
Make sure you have execution rights on the function. try creating the same function in a test schema and execute from same schema.
DeleteZ
Hi
ReplyDeleteactually I am working on sql server oracle is new to me
how to create test schema ..
This code is related to Oracle APEX. Please follow the documentation. I have provided enough details and a video how to do it.
DeleteZ
yes I followed each and every step of yours .. when I login with that user id 'robin' and pw 'vbc'
ReplyDeleteis showing
PLS-00905: object GB_7133_S11_PLSQL.VALIDATE_USER_FROM_DB is invalid
above error
what it means
thanks
Do you have permission to access APEX_UTIL user ? are you working in Oracle APEX application or something else ?
Deleteif you don't have permission then grant permissions on set_authentication_result package to your user.
thanks for this blog, its usefull for me but;
ReplyDeletewhen i try to login get this error:
"ORA-44004: invalid qualified SQL name"
Hi check this thread for solution..
Deletehttps://forums.oracle.com/forums/thread.jspa?threadID=2284388&start=15&tstart=0
"Give your packagename.function name in your custom authentication function like the below and check,
return final_users_security.valid_user
"
Hope it helps,
Z
It is very useful and simple explanation:) Thanks!
ReplyDelete