Signon Password Policies
I just recently got the requirement that user passwords should follow the password security policy of the client. Oracle eBS delivers a number of password policies which may fullfill the need in your organization but to make passwords more secure you have to extend the policies.
Of course it's possible to implement Oracle Access Manager combined with Oracle Internet Directory to hook in to Active Directory but that combi will not be used (yet :-)) so will also not be discussed in this article.
Profile Options
A number of profile options relate to the seeded delivered password policies.
By enabling the password expiration option on usernames they are enforced to change their password after a certain number of days or after logging in succesfully a number of times.
Custom Password Java Class
When you want to use custom password policies you have to use profile option Signon Password Custom. This profile must be set on the custom java class name which provides the custom policy. It's very important that profile Signon Password Hard To Guess is NULL when using custom password policies.
The custom java class you create should inherit the security class from eBS. Below an example of such a class
package oracle.apps.fnd.security;
import oracle.apps.fnd.common.VersionInfo;
// Referenced classes of package oracle.apps.fnd.security:
// PasswordValidation
public class AppsPasswordValidationCustom
implements PasswordValidation
{
public String getErrorStackApplicationName()
{
return "FND";
}
public String getErrorStackMessageName()
{
return m_errorStackMessageName;
}
public boolean validate(String username, String password)
{
if(password ==null || password.length() == 0 || username == null || username.length() == 0)
{
m_errorStackMessageName = "PASSWORD-INVALID";
return false;
}
if(password.length() < 8)
{
m_errorStackMessageName = "PASSWORD-INVALID-LENGTH";
return false;
}
if(!validateLettersAndDigits(password))
{
m_errorStackMessageName = "PASSWORD-INVALID-LETTER-NUMBER";
return false;
}
if(!validateNoUsername(username, password))
{
m_errorStackMessageName = "PASSWORD-INVALID-USERNAME";
return false;
}
if(!validateNoRepeats(password))
{
m_errorStackMessageName = "PASSWORD-INVALID-REPEATS";
return false;
}
return true;
}
private boolean validateLettersAndDigits(String p_password)
{
boolean flag = false;
boolean flag1 = false;
for(int i = 0; i < p_password.length(); i++)
{
if(Character.isLetter(p_password.charAt(i)))
flag = true;
if(Character.isDigit(p_password.charAt(i)))
flag1 = true;
}
return flag && flag1;
}
private boolean validateNoUsername(String p_username, String p_password)
{
return p_password.toUpperCase().indexOf(p_username.toUpperCase()) == -1;
}
private boolean validateNoRepeats(String p_password)
{
for(int i = 1; i < p_password.length(); i++)
if(p_password.charAt(i) == p_password.charAt(i - 1))
return false;
return true;
}
private String m_errorStackMessageName;
}
Provide your own validation functions within this class to incorporate your client specific policies.
Load your custom class to the database with executing the below command. After that run adadmin to recompile the APPS schema.
loadjava -user apps/<apps password> -verbose -resolve -force AppsPasswordValidationCustom.java
Check wether the class was loaded succesfully by running below SQL statement
SELECT dbms_java.longname(object_name), status
FROM user_objects
WHERE object_type = 'JAVA CLASS'
AND dbms_java.longname(object_name) like '%AppsPasswordValidationCustom';
After this went succesfully enter the name of your class within profile option Signon Password Custom being something like oracle.apps.fnd.security.AppsPasswordValidationCustom.
Of course it's possible to implement Oracle Access Manager combined with Oracle Internet Directory to hook in to Active Directory but that combi will not be used (yet :-)) so will also not be discussed in this article.
Profile Options
A number of profile options relate to the seeded delivered password policies.
- Signon Password Case: This profile will enable case sensitivity for password. To make it case sensitive it will make passwords more secure because combination of upper and lower characters will be used. When passwords are not case sensitive the entered password by the user will be uppered and validated against the encrypted password stored with the user.
- Signon Password Custom: This profile will provide the name of the custom java class which enables the use of custom, client specific, password policies.
- Signon Password Failure Limit: This profile provides the number of login attempts an user can do. When the number of attempts exceeds this setting the users' account will be blocked.
- Signon Password Hard To Guess: Setting this profile to Yes will provide the following password policies:
1) the password containts at least one letter AND at least one number
2) the password does not contain the username
3) the password doest not contain any repeating characters - Signon Password Length: This profile will give the minimum length of an user password
- Signon Password No Reuse: This profile will provide the number of days an user must wait before reusing an earlier used password.
By enabling the password expiration option on usernames they are enforced to change their password after a certain number of days or after logging in succesfully a number of times.
When you want to use custom password policies you have to use profile option Signon Password Custom. This profile must be set on the custom java class name which provides the custom policy. It's very important that profile Signon Password Hard To Guess is NULL when using custom password policies.
The custom java class you create should inherit the security class from eBS. Below an example of such a class
package oracle.apps.fnd.security;
import oracle.apps.fnd.common.VersionInfo;
// Referenced classes of package oracle.apps.fnd.security:
// PasswordValidation
public class AppsPasswordValidationCustom
implements PasswordValidation
{
public String getErrorStackApplicationName()
{
return "FND";
}
public String getErrorStackMessageName()
{
return m_errorStackMessageName;
}
public boolean validate(String username, String password)
{
if(password ==null || password.length() == 0 || username == null || username.length() == 0)
{
m_errorStackMessageName = "PASSWORD-INVALID";
return false;
}
if(password.length() < 8)
{
m_errorStackMessageName = "PASSWORD-INVALID-LENGTH";
return false;
}
if(!validateLettersAndDigits(password))
{
m_errorStackMessageName = "PASSWORD-INVALID-LETTER-NUMBER";
return false;
}
if(!validateNoUsername(username, password))
{
m_errorStackMessageName = "PASSWORD-INVALID-USERNAME";
return false;
}
if(!validateNoRepeats(password))
{
m_errorStackMessageName = "PASSWORD-INVALID-REPEATS";
return false;
}
return true;
}
private boolean validateLettersAndDigits(String p_password)
{
boolean flag = false;
boolean flag1 = false;
for(int i = 0; i < p_password.length(); i++)
{
if(Character.isLetter(p_password.charAt(i)))
flag = true;
if(Character.isDigit(p_password.charAt(i)))
flag1 = true;
}
return flag && flag1;
}
private boolean validateNoUsername(String p_username, String p_password)
{
return p_password.toUpperCase().indexOf(p_username.toUpperCase()) == -1;
}
private boolean validateNoRepeats(String p_password)
{
for(int i = 1; i < p_password.length(); i++)
if(p_password.charAt(i) == p_password.charAt(i - 1))
return false;
return true;
}
private String m_errorStackMessageName;
}
Provide your own validation functions within this class to incorporate your client specific policies.
Load your custom class to the database with executing the below command. After that run adadmin to recompile the APPS schema.
loadjava -user apps/<apps password> -verbose -resolve -force AppsPasswordValidationCustom.java
Check wether the class was loaded succesfully by running below SQL statement
SELECT dbms_java.longname(object_name), status
FROM user_objects
WHERE object_type = 'JAVA CLASS'
AND dbms_java.longname(object_name) like '%AppsPasswordValidationCustom';
After this went succesfully enter the name of your class within profile option Signon Password Custom being something like oracle.apps.fnd.security.AppsPasswordValidationCustom.