blob: 5410f40d5b5835847ba4482a2b9610886f31907e [file] [log] [blame]
/*
* Copyright 2005-2008 Les Hazlewood, Jeremy Haile
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsecurity.authc;
import java.net.InetAddress;
/**
* <p>A simple username/password authentication token to support the most widely-used authentication mechanism. This
* class also implements the {@link RememberMeAuthenticationToken RememberMeAuthenticationToken} to support
* &quot;Remember Me&quot; services across user sessions as well as the
* {@link InetAuthenticationToken InetAuthenticationToken} to retain the IP address location from where the
* authentication attempt is occuring.</p>
*
* <p>&quot;Remember Me&quot; authentications are disabled by default, but if the application developer wishes to allow
* it for a login attempt, all it has to do is call {@link #setRememberMe setRememberMe(true)}. If the underlying
* <tt>SecurityManager</tt> implementation also supports <tt>RememberMe</tt> services, the user's identity will be
* remembered across sessions.
*
* <p>Note that this class stores a password as a char[] instead of a String
* (which may seem more logical). This is because Strings are immutable and their
* internal value cannot be overwritten - meaning even a nulled String instance might be accessible in memory at a later
* time (e.g. memory dump). This is not good for sensitive information such as passwords. For more information, see the
* <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx">
* Java Cryptography Extension Reference Guide</a>.</p>
*
* <p>To avoid this possibility of later memory access, the application developer should always call
* {@link #clear() clear()} after using the token to perform a login attempt.</p>
*
* @since 0.1
* @author Jeremy Haile
* @author Les Hazlewood
*/
public class UsernamePasswordToken implements InetAuthenticationToken, RememberMeAuthenticationToken {
/*--------------------------------------------
| C O N S T A N T S |
============================================*/
/*--------------------------------------------
| I N S T A N C E V A R I A B L E S |
============================================*/
private String username;
private char[] password;
private boolean rememberMe = false;
private InetAddress inetAddress;
/*--------------------------------------------
| C O N S T R U C T O R S |
============================================*/
/**
* JavaBeans compatible no-arg constructor.
*/
public UsernamePasswordToken(){}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted
* during an authentication attempt, with a <tt>null</tt> {@link #getInetAddress() inetAddress} and a
* <tt>rememberMe</tt> default of <tt>false</tt>.
*
* @param username the username submitted for authentication
* @param password the password character array submitted for authentication
*/
public UsernamePasswordToken(final String username, final char[] password) {
this( username, password, false, null );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted
* during an authentication attempt, with a <tt>null</tt> {@link #getInetAddress() inetAddress} and
* a <tt>rememberMe</tt> default of <tt>false</tt>
*
* <p>This is a convience constructor and maintains the password internally via a character
* array, i.e. <tt>password.toCharArray();</tt>. Note that storing a password as a String
* in your code could have possible security implications as noted in the class JavaDoc.</p>
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
*/
public UsernamePasswordToken(final String username, final String password ) {
this( username, password.toCharArray(), false, null );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, the
* inetAddress from where the attempt is occurring, and a default <tt>rememberMe</tt> value of <tt>false</tt>
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
* @param inetAddress the inetAddress from where the attempt is occuring
*
* @since 0.2
*/
public UsernamePasswordToken(final String username, final char[] password, final InetAddress inetAddress ) {
this( username, password, false, inetAddress );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, the
* inetAddress from where the attempt is occurring, and a default <tt>rememberMe</tt> value of <tt>false</tt>
*
* <p>This is a convience constructor and maintains the password internally via a character
* array, i.e. <tt>password.toCharArray();</tt>. Note that storing a password as a String
* in your code could have possible security implications as noted in the class JavaDoc.</p>
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
* @param inetAddress the inetAddress from where the attempt is occuring
*
* @since 0.2
*/
public UsernamePasswordToken( final String username, final String password, final InetAddress inetAddress ) {
this( username, password.toCharArray(), false, inetAddress );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, as well as if the user
* wishes their identity to be remembered across sessions.
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
* @param rememberMe if the user wishes their identity to be remembered across sessions
*
* @since 0.9
*/
public UsernamePasswordToken(final String username, final char[] password, final boolean rememberMe ) {
this( username, password, rememberMe, null );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, as well as if the user
* wishes their identity to be remembered across sessions.
*
* <p>This is a convience constructor and maintains the password internally via a character
* array, i.e. <tt>password.toCharArray();</tt>. Note that storing a password as a String
* in your code could have possible security implications as noted in the class JavaDoc.</p>
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
* @param rememberMe if the user wishes their identity to be remembered across sessions
*
* @since 0.9
*/
public UsernamePasswordToken( final String username, final String password, final boolean rememberMe ) {
this( username, password.toCharArray(), rememberMe, null );
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
* wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
*
* @param username the username submitted for authentication
* @param password the password character array submitted for authentication
* @param rememberMe if the user wishes their identity to be remembered across sessions
* @param inetAddress the inetAddress from where the attempt is occuring
*
* @since 0.9
*/
public UsernamePasswordToken( final String username, final char[] password,
final boolean rememberMe, final InetAddress inetAddress ) {
this.username = username;
this.password = password;
this.rememberMe = rememberMe;
this.inetAddress = inetAddress;
}
/**
* Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
* wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
*
* <p>This is a convience constructor and maintains the password internally via a character
* array, i.e. <tt>password.toCharArray();</tt>. Note that storing a password as a String
* in your code could have possible security implications as noted in the class JavaDoc.</p>
*
* @param username the username submitted for authentication
* @param password the password string submitted for authentication
* @param rememberMe if the user wishes their identity to be remembered across sessions
* @param inetAddress the inetAddress from where the attempt is occuring
*
* @since 0.9
*/
public UsernamePasswordToken( final String username, final String password,
final boolean rememberMe, final InetAddress inetAddress ) {
this( username, password.toCharArray(), rememberMe, inetAddress );
}
/*--------------------------------------------
| A C C E S S O R S / M O D I F I E R S |
============================================*/
/**
* Returns the username submitted during an authentication attempt.
* @return the username submitted during an authentication attempt.
*/
public String getUsername() {
return username;
}
/**
* Sets the username for submission during an authentication attempt.
* @param username the username to be used for submission during an authentication attempt.
*/
public void setUsername( String username ) {
this.username = username;
}
/**
* Returns the password submitted during an authentication attempt as a character array.
* @return the password submitted during an authentication attempt as a character array.
*/
public char[] getPassword() {
return password;
}
/**
* Sets the password for submission during an authentication attempt.
* @param password the password to be used for submission during an authentication attemp.
*/
public void setPassword( char[] password ) {
this.password = password;
}
/**
* Simply returns {@link #getUsername() getUsername()}.
* @see org.jsecurity.authc.AuthenticationToken#getPrincipal()
* @return the {@link #getUsername() username}.
*/
public Object getPrincipal() {
return getUsername();
}
/**
* Returns the {@link #getPassword() password} char array.
* @see org.jsecurity.authc.AuthenticationToken#getCredentials()
* @return the {@link #getPassword() password} char array.
*/
public Object getCredentials() {
return getPassword();
}
/**
* Returns the inetAddress from where the authentication attempt occurs. May be <tt>null</tt> if the inetAddress
* is unknown or explicitly omitted. It is up to the Authenticator implementation processing this token if
* an authentication attempt without an inetAddress is valid or not.
*
* <p>(JSecurity's default Authenticator
* allows <tt>null</tt> IPs to support localhost and proxy server environments).</p>
* @return the inetAddress from where the authentication attempt occurs, or <tt>null</tt> if it is unknown or
* explicitly omitted.
* @since 0.2
*/
public InetAddress getInetAddress() {
return inetAddress;
}
/**
* Sets the inetAddress from where the authentication attempt occurs. It is up to the Authenticator
* implementation processing this token if an authentication attempt without an inetAddress is valid or not.
*
* <p>(JSecurity's default Authenticator
* allows <tt>null</tt> IPs to allow localhost and proxy server environments).</p>
* @param inetAddress the inetAddress from where the authentication attempt occurs.
* @since 0.2
*/
public void setInetAddress( InetAddress inetAddress ) {
this.inetAddress = inetAddress;
}
/**
* Returns <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered
* across sessions, <tt>false</tt> otherwise. Unless overridden, this value is <tt>false</tt> by default.
* @return <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered
* across sessions, <tt>false</tt> otherwise (<tt>false</tt> by default).
*
* @since 0.9
*/
public boolean isRememberMe() {
return rememberMe;
}
/**
* Sets if the submitting user wishes their identity (pricipal(s)) to be remembered across sessions. Unless
* overridden, the default value is <tt>false</tt>, indicating <em>not</em> to be remembered across sessions.
* @param rememberMe value inidicating if the user wishes their identity (principal(s)) to be remembered across
* sessions.
*
* @since 0.9
*/
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
/*--------------------------------------------
| M E T H O D S |
============================================*/
/**
* Clears out (nulls) the username, password, rememberMe, and inetAddress. The password bytes are explicitly set to
* <tt>0x00</tt> before nulling to eliminate the possibility of memory access at a later time.
*/
public void clear() {
this.username = null;
this.inetAddress = null;
this.rememberMe = false;
if( this.password != null ) {
for( int i = 0; i < password.length; i++ ) {
this.password[i] = 0x00;
}
this.password = null;
}
}
/**
* Returns the String representation. It does not include the password in the resulting
* string for security reasons to prevent accidentially printing out a password
* that might be widely viewable).
*
* @return the String representation of the <tt>UsernamePasswordToken</tt>, omitting
* the password.
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append( getClass().getName() );
sb.append( " - " );
sb.append( username );
sb.append( ", rememberMe=" ).append( rememberMe );
if ( inetAddress != null ) {
sb.append( " (" ).append( inetAddress ).append( ")");
}
return sb.toString();
}
}