Compile the plug-in module.
44
Configuring a Customized External Authentication Plug-in 44-1
44
Configuring a Customized External Authentication Plug-in
You can store user security credentials in a repository other than Oracle Internet Directory—for example, a database or another LDAP directory—and use these
credentials for user authentication to Oracle components. You do not need to store the credentials in Oracle Internet Directory and then worry about keeping them
synchronized. Authenticating a user by way of credentials stored in an external repository is called external authentication.
This chapter contains these topics:
■
Introduction to Configuring a Customized External Authentication Plug-in
■
Installing, Configuring, and Enabling the External Authentication Plug-in
■
Debugging the External Authentication Plug-in
■
Creating the PLSQL Package oidexaup.sql
Introduction to Configuring a Customized External Authentication Plug-in
Authentication that relies on security credentials stored in Oracle Internet Directory is called native authentication. When a user enters her security credentials, the directory
server compares them with the credentials stored in Oracle Internet Directory. If the credentials match, then the directory server authenticates the user.
By contrast, authentication that relies on security credentials stored in a directory other than Oracle Internet Directory is called external authentication. When a user enters her
security credentials, the directory server compares them with the credentials stored in the other directory. This is done by using:
■
A PLSQL program that does the external authentication work
■
An external authentication plug-in that invokes this PLSQL program
Installing, Configuring, and Enabling the External Authentication Plug-in
This example uses the PLSQL program, oidexaup.sql. Creating the PLSQL
Package oidexaup.sql on page 44-3 describes this program. This package is used for
installing the external authentication plug-in PLSQL package. It contains:
■
Two plug-ins: namely, when_compare_replace and when_modify_replace
Note: All references to Oracle Single Sign-On in this chapter refer to
Oracle Single Sign-On 10g 10.1.4.3.0 or later.
44-2 Oracle Fusion Middleware Administrators Guide for Oracle Internet Directory
■
One utility function: namely, get_nickname The integrated package is the plug-in package, OIDEXTAUTH. It can also serve as a
template to modify according to the requirements of your deployment. To install, configure, and enable the external authentication plug-in, follow these steps:
1.
Implement your standalone external authentication PLSQL program. For example, if you want to authenticate users by using user names and passwords,
then you should have a PLSQL program which takes these two parameters.
In our sample code, oidexaup.sql, auth_external is the program package name, and authenticate_user is the function that does the authentication. you
must make sure that this standalone program is working properly before you move on to next steps.
2.
Integrate this standalone program into the plug-in modules.
3.
Load the plug-in package into database. In this example, we enter: sqlplus odsodspwd oidexaup.sql
4.
Register the plug-ins. Do this by creating and uploading an LDIF file that provides the directory server with the necessary information to invoke the plug-in.
5.
This example uses a file named oidexauth.ldif, which contains the following: dn: cn=whencompare,cn=plugin,cn=subconfigsubentry
objectclass:orclPluginConfig objectclass:top
orclpluginname:oidextauth orclplugintype:configuration
orclplugintiming:when orclpluginldapoperation:ldapcompare
orclpluginenable:1 orclpluginversion:1.0.1
orclPluginIsReplace:1 cn:whencompare
orclpluginsubscriberdnlist:dc=com;o=IMC,c=US orclpluginattributelist:userpassword
orclpluginrequestgroup:prgdn
dn: cn=whenmodify,cn=plugin,cn=subconfigsubentry objectclass:orclPluginConfig
objectclass:top orclpluginname:oidextauth
orclplugintype:configuration orclplugintiming:when
orclpluginldapoperation:ldapmodify orclpluginenable:1
orclpluginversion:1.0.1 orclPluginIsReplace:1
cn:whenmodify orclpluginsubscriberdnlist:dc=com;o=IMC,c=US
orclpluginattributelist:userpassword orclpluginrequestgroup:prgdn
In this file, we notify the directory server that, whenever there is an ldapcompare or ldapmodify request, there are two plug-ins to be invoked.
We use orclpluginsubscriberdnlist:dc=com;o=IMC,c=US so that plug-ins are ONLY invoked if the target entry is under dc=com or o=IMC,c=US.
Configuring a Customized External Authentication Plug-in 44-3
Replace prgdn with the plug-in request group DN. This is an optional, recommended security feature. For integrating with Oracle Single Sign-On, this
value is a required field. Only members of the group entered can invoke the plug-ins. You may enter multiple groups. Use a semicolon to separate entries.
The recommended defaults are: cn=OracleUserSecurityAdmins,cn=Groups,cn=OracleContext and
cn=OracleDASAdminGroup,cn=Groups,cn=OracleContext,o=default_ subscriber,dc=com. Note that the Oracle Single Sign-On server is a member of
the first group. Also, be sure to replace o=default_subscriber with the correct value for your deployment environment.
To add this file to the directory, enter the following: ldapadd -p portnum -h hostname -D cn=orcladmin -q -v \
-f oidexauth.ldif Now, everything should be ready. Use the ldapcompare command-line tool to verify
that the plug-in and authentication program are working properly before you try to authenticate the user from Oracle Single Sign-On.
In our example, we also provide the plug-in code for externally modifying user password.
Debugging the External Authentication Plug-in
Turn on directory server plug-in to help you to examine the process and content of plug-ins.
To setup directory server plug-in debugging, execute the following command: sqlplus ods ORACLE_HOMEldapadminoidspdsu.sql
To enable directory server plug-in debugging, execute the following command: sqlplus ods ORACLE_HOMEldapadminoidspdon.sql
To disable directory server plug-in debugging, execute the following command: sqlplus ods ORACLE_HOMEldapadminoidspdof.sql
To show directory server plug-in debugging messages, execute the following command:
sqlplus ods ORACLE_HOMEldapadminoidspdsh.sql To delete directory server plug-in debugging messages, please execute the following
command: sqlplus ods ORACLE_HOMEldapadminoidspdde.sql
Creating the PLSQL Package oidexaup.sql
The script oidexaup.sql, as used in this example, contains the following: CREATE OR REPLACE PACKAGE OIDEXTAUTH AS
PROCEDURE when_compare_replace ldapplugincontext IN ODS.plugincontext, result OUT INTEGER,
dn IN VARCHAR2, attrname IN VARCHAR2,
attrval IN VARCHAR2,
44-4 Oracle Fusion Middleware Administrators Guide for Oracle Internet Directory
rc OUT INTEGER, errormsg OUT VARCHAR2
; PROCEDURE when_modify_replace ldapplugincontext IN ODS.plugincontext,
dn IN VARCHAR2, mods IN ODS.modlist,
rc OUT INTEGER, errormsg OUT VARCHAR2
; FUNCTION get_nickname dn IN VARCHAR2,
my_session IN DBMS_LDAP.session RETURN VARCHAR2;
END OIDEXTAUTH; SHOW ERROR
CREATE OR REPLACE PACKAGE BODY OIDEXTAUTH AS -- We use this function to convert the dn to nickname.
-- When OID server receives the ldapcompare request, it -- only has the dn information. We need to use DBMS_LDAP_UTL
-- package to find out the nickname attribute value of -- the entry.
FUNCTION get_nickname dn IN VARCHAR2, my_session IN DBMS_LDAP.session
RETURN VARCHAR2 IS
my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION; my_property_names DBMS_LDAP.STRING_COLLECTION;
my_property_values DBMS_LDAP.STRING_COLLECTION; user_handle DBMS_LDAP_UTL.HANDLE;
user_id VARCHAR22000; user_type PLS_INTEGER;
user_nickname VARCHAR2256 DEFAULT NULL; my_attrs DBMS_LDAP.STRING_COLLECTION;
retval PLS_INTEGER; BEGIN
plg_debug === Beginning of get_nickname === ; user_type := DBMS_LDAP_UTL.TYPE_DN;
user_id := dn; retval := DBMS_LDAP_UTL.create_user_handleuser_handle, user_type, user_id;
plg_debugcreate_user_handle Returns || To_charretval; retval := DBMS_LDAP_UTL.get_user_propertiesmy_session,
user_handle, my_attrs,
DBMS_LDAP_UTL.NICKNAME_PROPERTY, my_pset_coll;
plg_debug get_user_properties Returns || To_charretval;
Configuring a Customized External Authentication Plug-in 44-5
IF my_pset_coll.COUNT 0 THEN FOR i IN my_pset_coll.first .. my_pset_coll.last LOOP
retval := DBMS_LDAP_UTL.get_property_namesmy_pset_colli, my_property_names;
IF my_property_names.COUNT 0 THEN FOR j IN my_property_names.first .. my_property_names.last LOOP
retval := DBMS_LDAP_UTL.get_property_valuesmy_pset_colli, my_property_namesj,
my_property_values; IF my_property_values.COUNT 0 THEN
FOR k IN my_property_values.FIRST..my_property_values.LAST LOOP
user_nickname := my_property_valuesk; plg_debug user nickname = || user_nickname;
END LOOP; END IF;
END LOOP; END IF; -- IF my_property_names.count 0
END LOOP; END IF; -- If my_pset_coll.count 0
plg_debug got user_nickname: || user_nickname;
-- Free my_properties IF my_pset_coll.count 0 then
DBMS_LDAP_UTL.free_propertyset_collectionmy_pset_coll; END IF;
DBMS_LDAP_UTL.free_handleuser_handle; RETURN user_nickname;
EXCEPTION WHEN OTHERS THEN
plg_debugException in get_nickname. Error code is || to_ charsqlcode;
plg_debug || Sqlerrm; RETURN NULL;
END;
PROCEDURE when_compare_replace ldapplugincontext IN ODS.plugincontext, result OUT INTEGER,
dn IN VARCHAR2, attrname IN VARCHAR2,
attrval IN VARCHAR2, rc OUT INTEGER,
errormsg OUT VARCHAR2 IS
retval pls_integer; lresult BOOLEAN;
my_session DBMS_LDAP.session; my_property_names DBMS_LDAP.STRING_COLLECTION;
my_property_values DBMS_LDAP.STRING_COLLECTION; my_attrs DBMS_LDAP.STRING_COLLECTION;
my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION; user_handle DBMS_LDAP_UTL.HANDLE;
44-6 Oracle Fusion Middleware Administrators Guide for Oracle Internet Directory
user_id VARCHAR22000; user_type PLS_INTEGER;
user_nickname VARCHAR260; remote_dn VARCHAR2256;
i PLS_INTEGER; j PLS_INTEGER;
k PLS_INTEGER; BEGIN
plg_debug === Begin of WHEN-COMPARE-REPLACE plug-in; plg_debug DN = || dn;
plg_debug Attr = || attrname; --plg_debug Attrval = || attrval;
DBMS_LDAP.USE_EXCEPTION := FALSE; errormsg := No error msg;
rc := 0; -- converting dn to nickname
my_session := LDAP_PLUGIN.initldapplugincontext; plg_debug ldap_session = || RAWTOHEXSUBSTRmy_session,1,8;
retval := LDAP_PLUGIN.simple_bind_sldapplugincontext, my_session; plg_debug simple_bind_res = || TO_CHARretval;
user_nickname := get_nicknamedn, my_session; plg_debug user_nickname = || user_nickname;
-- unbind from the directory retval := DBMS_LDAP.unbind_smy_session;
plg_debug unbind_res Returns || To_charretval;
IF user_nickname IS NULL THEN result := 32;
errormsg := Cant find the nickname; plg_debug Cant find the nickname;
RETURN; END IF;
plg_debug === Now go to extauth ; BEGIN
retval := auth_external.authenticate_useruser_nickname, attrval; plg_debug auth_external.authenticate_user returns = || True;
result := 6; -- compare result is TRUE EXCEPTION
WHEN OTHERS THEN result := 5; -- compare result is FALSE
plg_debug auth_external.authenticate_user returns = || False; RETURN;
END; plg_debug === End of WHEN-COMPARE-REPLACE plug-in;
EXCEPTION WHEN OTHERS THEN
rc := 1; errormsg := Exception: when_compare_replace plugin;
plg_debug EXCEPTION: || retval;
Configuring a Customized External Authentication Plug-in 44-7
plg_debugException in when_compare. Error code is || to_ charsqlcode;
plg_debug || Sqlerrm; END;
PROCEDURE when_modify_replace ldapplugincontext IN ODS.plugincontext, dn IN VARCHAR2,
mods IN ODS.modlist, rc OUT INTEGER,
errormsg OUT VARCHAR2 IS
retval pls_integer; lresult BOOLEAN;
my_session DBMS_LDAP.SESSION; my_property_names DBMS_LDAP.STRING_COLLECTION;
my_property_values DBMS_LDAP.STRING_COLLECTION; my_attrs DBMS_LDAP.STRING_COLLECTION;
my_modval DBMS_LDAP.BERVAL_COLLECTION; my_pset_coll DBMS_LDAP_UTL.PROPERTY_SET_COLLECTION;
user_handle DBMS_LDAP_UTL.HANDLE;
l_mod_array RAW32; user_id VARCHAR22000;
user_type PLS_INTEGER; user_nickname VARCHAR22000;
old_passwd VARCHAR260 DEFAULT NULL; new_passwd VARCHAR260 DEFAULT NULL;
remote_dn VARCHAR2256; i PLS_INTEGER;
j PLS_INTEGER; k PLS_INTEGER;
BEGIN plg_debug === Begin of WHEN-MODIFY-REPLACE plug-in;
DBMS_LDAP.USE_EXCEPTION := FALSE; user_type := DBMS_LDAP_UTL.TYPE_DN;
user_id := dn; -- converting dn to nickname
my_session := LDAP_PLUGIN.initldapplugincontext; plg_debug ldap_session = || RAWTOHEXSUBSTRmy_session,1,8;
retval := LDAP_PLUGIN.simple_bind_sldapplugincontext, my_session; plg_debug simple_bind_res = || TO_CHARretval;
user_nickname := get_nicknamedn, my_session; plg_debug user_nickname = || user_nickname;
-- unbind from the directory retval := DBMS_LDAP.unbind_smy_session;
FOR l_counter1 IN 1..mods.COUNT LOOP IF modsl_counter1.operation = 2 AND
modsl_counter1.type = userpassword THEN FOR l_counter2 IN 1..modsl_counter1.vals.COUNT LOOP