org.owasp.esapi.reference
Class FileBasedAuthenticator

java.lang.Object
  extended by org.owasp.esapi.reference.AbstractAuthenticator
      extended by org.owasp.esapi.reference.FileBasedAuthenticator
All Implemented Interfaces:
Authenticator

public class FileBasedAuthenticator
extends AbstractAuthenticator

Reference implementation of the Authenticator interface. This reference implementation is backed by a simple text file that contains serialized information about users. Many organizations will want to create their own implementation of the methods provided in the Authenticator interface backed by their own user repository. This reference implementation captures information about users in a simple text file format that contains user information separated by the pipe "|" character. Here's an example of a single line from the users.txt file:

 

account id | account name | hashed password | roles | lockout | status | old password hashes | last hostname | last change | last login | last failed | expiration | failed --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1203123710837 | mitch | 44k/NAzQUlrCq9musTGGkcMNmdzEGJ8w8qZTLzpxLuQ= | admin,user | unlocked | enabled | u10dW4vTo3ZkoM5xP+blayWCz7KdPKyKUojOn9GJobg= | 192.168.1.255 | 1187201000926 | 1187200991568 | 1187200605330 | 2187200605330 | 1

Since:
June 1, 2007
Author:
Jeff Williams at Aspect Security, Chris Schmidt (chrisisbeef .at. gmail.com) Digital Ritual Software
See Also:
Authenticator

Field Summary
 
Fields inherited from class org.owasp.esapi.reference.AbstractAuthenticator
USER
 
Method Summary
 void changePassword(User user, java.lang.String currentPassword, java.lang.String newPassword, java.lang.String newPassword2)
          Changes the password for the specified user.
 User createUser(java.lang.String accountName, java.lang.String password1, java.lang.String password2)
          Creates a new User with the information provided.
 java.lang.String generateStrongPassword()
          Generate a strong password.
 java.lang.String generateStrongPassword(User user, java.lang.String oldPassword)
          Generate strong password that takes into account the user's information and old password.
static Authenticator getInstance()
           
 User getUser(long accountId)
          Returns the User matching the provided accountId.
 User getUser(java.lang.String accountName)
          Returns the User matching the provided accountName.
 java.util.Set getUserNames()
          Gets a collection containing all the existing user names.
 java.lang.String hashPassword(java.lang.String password, java.lang.String accountName)
          Returns a string representation of the hashed password, using the accountName as the salt.
protected  void loadUsersIfNecessary()
          Load users if they haven't been loaded in a while.
protected  void loadUsersImmediately()
           
static void main(java.lang.String[] args)
          Fail safe main program to add or update an account in an emergency.
 void removeUser(java.lang.String accountName)
          Removes the account of the specified accountName.
 void saveUsers()
          Saves the user database to the file system.
protected  void saveUsers(java.io.PrintWriter writer)
          Save users.
 void verifyAccountNameStrength(java.lang.String newAccountName)
          Ensures that the account name passes site-specific complexity requirements, like minimum length.
 boolean verifyPassword(User user, java.lang.String password)
          Verify that the supplied password matches the password for this user.
 void verifyPasswordStrength(java.lang.String oldPassword, java.lang.String newPassword, User user)
          Ensures that the password meets site-specific complexity requirements, like length or number of character sets.
 
Methods inherited from class org.owasp.esapi.reference.AbstractAuthenticator
clearCurrent, exists, getCurrentUser, getUserFromRememberToken, getUserFromSession, login, login, logout, setCurrentUser
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

getInstance

public static Authenticator getInstance()

main

public static void main(java.lang.String[] args)
                 throws java.lang.Exception
Fail safe main program to add or update an account in an emergency.

Warning: this method does not perform the level of validation and checks generally required in ESAPI, and can therefore be used to create a username and password that do not comply with the username and password strength requirements.

Example: Use this to add the alice account with the admin role to the users file:

 

java -Dorg.owasp.esapi.resources="/path/resources" -classpath esapi.jar org.owasp.esapi.Authenticator alice password admin

Parameters:
args - the arguments (username, password, role)
Throws:
java.lang.Exception - the exception

createUser

public User createUser(java.lang.String accountName,
                       java.lang.String password1,
                       java.lang.String password2)
                throws AuthenticationException
Creates a new User with the information provided. Implementations should check accountName and password for proper format and strength against brute force attacks ( verifyAccountNameStrength(String), verifyPasswordStrength(String, String) ). Two copies of the new password are required to encourage user interface designers to include a "re-type password" field in their forms. Implementations should verify that both are the same.

Parameters:
accountName - the account name of the new user
password1 - the password of the new user
password2 - the password of the new user. This field is to encourage user interface designers to include two password fields in their forms.
Returns:
the User that has been created
Throws:
AuthenticationException - if user creation fails due to any of the qualifications listed in this method's description

generateStrongPassword

public java.lang.String generateStrongPassword()
Generate a strong password. Implementations should use a large character set that does not include confusing characters, such as i I 1 l 0 o and O. There are many algorithms to generate strong memorable passwords that have been studied in the past.

Returns:
a password with strong password strength

changePassword

public void changePassword(User user,
                           java.lang.String currentPassword,
                           java.lang.String newPassword,
                           java.lang.String newPassword2)
                    throws AuthenticationException
Changes the password for the specified user. This requires the current password, as well as the password to replace it with. The new password should be checked against old hashes to be sure the new password does not closely resemble or equal any recent passwords for that User. Password strength should also be verified. This new password must be repeated to ensure that the user has typed it in correctly.

Parameters:
user - the user to change the password for
currentPassword - the current password for the specified user
newPassword - the new password to use
newPassword2 - a verification copy of the new password
Throws:
AuthenticationException - if any errors occur

verifyPassword

public boolean verifyPassword(User user,
                              java.lang.String password)
Verify that the supplied password matches the password for this user. Password should be stored as a hash. It is recommended you use the hashPassword(password, accountName) method in this class. This method is typically used for "reauthentication" for the most sensitive functions, such as transactions, changing email address, and changing other account information.

Parameters:
user - the user who requires verification
password - the hashed user-supplied password
Returns:
true, if the password is correct for the specified user

generateStrongPassword

public java.lang.String generateStrongPassword(User user,
                                               java.lang.String oldPassword)
Generate strong password that takes into account the user's information and old password. Implementations should verify that the new password does not include information such as the username, fragments of the old password, and other information that could be used to weaken the strength of the password.

Parameters:
user - the user whose information to use when generating password
oldPassword - the old password to use when verifying strength of new password. The new password may be checked for fragments of oldPassword.
Returns:
a password with strong password strength

getUser

public User getUser(long accountId)
Returns the User matching the provided accountId. If the accoundId is not found, an Anonymous User or null may be returned.

Parameters:
accountId - the account id
Returns:
the matching User object, or the Anonymous User if no match exists

getUser

public User getUser(java.lang.String accountName)
Returns the User matching the provided accountName. If the accoundId is not found, an Anonymous User or null may be returned.

Parameters:
accountName - the account name
Returns:
the matching User object, or the Anonymous User if no match exists

getUserNames

public java.util.Set getUserNames()
Gets a collection containing all the existing user names.

Returns:
a set of all user names

hashPassword

public java.lang.String hashPassword(java.lang.String password,
                                     java.lang.String accountName)
                              throws EncryptionException
Returns a string representation of the hashed password, using the accountName as the salt. The salt helps to prevent against "rainbow" table attacks where the attacker pre-calculates hashes for known strings. This method specifies the use of the user's account name as the "salt" value. The Encryptor.hash method can be used if a different salt is required.

Parameters:
password - the password to hash
accountName - the account name to use as the salt
Returns:
the hashed password
Throws:
EncryptionException

loadUsersIfNecessary

protected void loadUsersIfNecessary()
Load users if they haven't been loaded in a while.


loadUsersImmediately

protected void loadUsersImmediately()

removeUser

public void removeUser(java.lang.String accountName)
                throws AuthenticationException
Removes the account of the specified accountName.

Parameters:
accountName - the account name to remove
Throws:
AuthenticationException - the authentication exception if user does not exist

saveUsers

public void saveUsers()
               throws AuthenticationException
Saves the user database to the file system. In this implementation you must call save to commit any changes to the user file. Otherwise changes will be lost when the program ends.

Throws:
AuthenticationException - if the user file could not be written

saveUsers

protected void saveUsers(java.io.PrintWriter writer)
                  throws AuthenticationCredentialsException
Save users.

Parameters:
writer - the print writer to use for saving
Throws:
AuthenticationCredentialsException

verifyAccountNameStrength

public void verifyAccountNameStrength(java.lang.String newAccountName)
                               throws AuthenticationException
Ensures that the account name passes site-specific complexity requirements, like minimum length.

This implementation simply verifies that account names are at least 5 characters long. This helps to defeat a brute force attack, however the real strength comes from the name length and complexity.

Parameters:
newAccountName -
Throws:
AuthenticationException - if account name does not meet complexity requirements

verifyPasswordStrength

public void verifyPasswordStrength(java.lang.String oldPassword,
                                   java.lang.String newPassword,
                                   User user)
                            throws AuthenticationException
Ensures that the password meets site-specific complexity requirements, like length or number of character sets. This method takes the old password so that the algorithm can analyze the new password to see if it is too similar to the old password. Note that this has to be invoked when the user has entered the old password, as the list of old credentials stored by ESAPI is all hashed. Additionally, the user object is taken in order to verify the password and account name differ.

This implementation checks: - for any 3 character substrings of the old password - for use of a length * character sets > 16 (where character sets are upper, lower, digit, and special jtm - 11/16/2010 - added check to verify pw != username (fix for http://code.google.com/p/owasp-esapi-java/issues/detail?id=108)

Parameters:
oldPassword - the old password
newPassword - the new password
user - the user
Throws:
AuthenticationException - if newPassword is too similar to oldPassword or if newPassword does not meet complexity requirements


Copyright © 2011 The Open Web Application Security Project (OWASP). All Rights Reserved.