Coverage Report - org.apache.shiro.authc.UsernamePasswordToken
 
Classes in this File Line Coverage Branch Coverage Complexity
UsernamePasswordToken
45%
24/53
28%
4/14
1.333
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.authc;
 20  
 
 21  
 /**
 22  
  * <p>A simple username/password authentication token to support the most widely-used authentication mechanism.  This
 23  
  * class also implements the {@link RememberMeAuthenticationToken RememberMeAuthenticationToken} interface to support
 24  
  * &quot;Remember Me&quot; services across user sessions as well as the
 25  
  * {@link org.apache.shiro.authc.HostAuthenticationToken HostAuthenticationToken} interface to retain the host name
 26  
  * or IP address location from where the authentication attempt is occuring.</p>
 27  
  * <p/>
 28  
  * <p>&quot;Remember Me&quot; authentications are disabled by default, but if the application developer wishes to allow
 29  
  * it for a login attempt, all that is necessary is to call {@link #setRememberMe setRememberMe(true)}.  If the underlying
 30  
  * <tt>SecurityManager</tt> implementation also supports <tt>RememberMe</tt> services, the user's identity will be
 31  
  * remembered across sessions.
 32  
  * <p/>
 33  
  * <p>Note that this class stores a password as a char[] instead of a String
 34  
  * (which may seem more logical).  This is because Strings are immutable and their
 35  
  * internal value cannot be overwritten - meaning even a nulled String instance might be accessible in memory at a later
 36  
  * time (e.g. memory dump).  This is not good for sensitive information such as passwords. For more information, see the
 37  
  * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx">
 38  
  * Java Cryptography Extension Reference Guide</a>.</p>
 39  
  * <p/>
 40  
  * <p>To avoid this possibility of later memory access, the application developer should always call
 41  
  * {@link #clear() clear()} after using the token to perform a login attempt.</p>
 42  
  *
 43  
  * @since 0.1
 44  
  */
 45  
 public class UsernamePasswordToken implements HostAuthenticationToken, RememberMeAuthenticationToken {
 46  
 
 47  
     /*--------------------------------------------
 48  
     |             C O N S T A N T S             |
 49  
     ============================================*/
 50  
 
 51  
     /*--------------------------------------------
 52  
     |    I N S T A N C E   V A R I A B L E S    |
 53  
     ============================================*/
 54  
     /**
 55  
      * The username
 56  
      */
 57  
     private String username;
 58  
 
 59  
     /**
 60  
      * The password, in char[] format
 61  
      */
 62  
     private char[] password;
 63  
 
 64  
     /**
 65  
      * Whether or not 'rememberMe' should be enabled for the corresponding login attempt;
 66  
      * default is <code>false</code>
 67  
      */
 68  42
     private boolean rememberMe = false;
 69  
 
 70  
     /**
 71  
      * The location from where the login attempt occurs, or <code>null</code> if not known or explicitly
 72  
      * omitted.
 73  
      */
 74  
     private String host;
 75  
 
 76  
     /*--------------------------------------------
 77  
     |         C O N S T R U C T O R S           |
 78  
     ============================================*/
 79  
 
 80  
     /**
 81  
      * JavaBeans compatible no-arg constructor.
 82  
      */
 83  0
     public UsernamePasswordToken() {
 84  0
     }
 85  
 
 86  
     /**
 87  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted
 88  
      * during an authentication attempt, with a <tt>null</tt> {@link #getHost() host} and a
 89  
      * <tt>rememberMe</tt> default of <tt>false</tt>.
 90  
      *
 91  
      * @param username the username submitted for authentication
 92  
      * @param password the password character array submitted for authentication
 93  
      */
 94  
     public UsernamePasswordToken(final String username, final char[] password) {
 95  0
         this(username, password, false, null);
 96  0
     }
 97  
 
 98  
     /**
 99  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted
 100  
      * during an authentication attempt, with a <tt>null</tt> {@link #getHost() host} and
 101  
      * a <tt>rememberMe</tt> default of <tt>false</tt>
 102  
      * <p/>
 103  
      * <p>This is a convience constructor and maintains the password internally via a character
 104  
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
 105  
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
 106  
      *
 107  
      * @param username the username submitted for authentication
 108  
      * @param password the password string submitted for authentication
 109  
      */
 110  
     public UsernamePasswordToken(final String username, final String password) {
 111  39
         this(username, password != null ? password.toCharArray() : null, false, null);
 112  39
     }
 113  
 
 114  
     /**
 115  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, the
 116  
      * inetAddress from where the attempt is occurring, and a default <tt>rememberMe</tt> value of <tt>false</tt>
 117  
      *
 118  
      * @param username the username submitted for authentication
 119  
      * @param password the password string submitted for authentication
 120  
      * @param host     the host name or IP string from where the attempt is occuring
 121  
      * @since 0.2
 122  
      */
 123  
     public UsernamePasswordToken(final String username, final char[] password, final String host) {
 124  0
         this(username, password, false, host);
 125  0
     }
 126  
 
 127  
     /**
 128  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, the
 129  
      * inetAddress from where the attempt is occurring, and a default <tt>rememberMe</tt> value of <tt>false</tt>
 130  
      * <p/>
 131  
      * <p>This is a convience constructor and maintains the password internally via a character
 132  
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
 133  
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
 134  
      *
 135  
      * @param username the username submitted for authentication
 136  
      * @param password the password string submitted for authentication
 137  
      * @param host     the host name or IP string from where the attempt is occuring
 138  
      * @since 1.0
 139  
      */
 140  
     public UsernamePasswordToken(final String username, final String password, final String host) {
 141  3
         this(username, password != null ? password.toCharArray() : null, false, host);
 142  3
     }
 143  
 
 144  
     /**
 145  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, as well as if the user
 146  
      * wishes their identity to be remembered across sessions.
 147  
      *
 148  
      * @param username   the username submitted for authentication
 149  
      * @param password   the password string submitted for authentication
 150  
      * @param rememberMe if the user wishes their identity to be remembered across sessions
 151  
      * @since 0.9
 152  
      */
 153  
     public UsernamePasswordToken(final String username, final char[] password, final boolean rememberMe) {
 154  0
         this(username, password, rememberMe, null);
 155  0
     }
 156  
 
 157  
     /**
 158  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, as well as if the user
 159  
      * wishes their identity to be remembered across sessions.
 160  
      * <p/>
 161  
      * <p>This is a convience constructor and maintains the password internally via a character
 162  
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
 163  
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
 164  
      *
 165  
      * @param username   the username submitted for authentication
 166  
      * @param password   the password string submitted for authentication
 167  
      * @param rememberMe if the user wishes their identity to be remembered across sessions
 168  
      * @since 0.9
 169  
      */
 170  
     public UsernamePasswordToken(final String username, final String password, final boolean rememberMe) {
 171  0
         this(username, password != null ? password.toCharArray() : null, rememberMe, null);
 172  0
     }
 173  
 
 174  
     /**
 175  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
 176  
      * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
 177  
      *
 178  
      * @param username   the username submitted for authentication
 179  
      * @param password   the password character array submitted for authentication
 180  
      * @param rememberMe if the user wishes their identity to be remembered across sessions
 181  
      * @param host       the host name or IP string from where the attempt is occuring
 182  
      * @since 1.0
 183  
      */
 184  
     public UsernamePasswordToken(final String username, final char[] password,
 185  42
                                  final boolean rememberMe, final String host) {
 186  
 
 187  42
         this.username = username;
 188  42
         this.password = password;
 189  42
         this.rememberMe = rememberMe;
 190  42
         this.host = host;
 191  42
     }
 192  
 
 193  
 
 194  
     /**
 195  
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
 196  
      * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
 197  
      * <p/>
 198  
      * <p>This is a convience constructor and maintains the password internally via a character
 199  
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
 200  
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
 201  
      *
 202  
      * @param username   the username submitted for authentication
 203  
      * @param password   the password string submitted for authentication
 204  
      * @param rememberMe if the user wishes their identity to be remembered across sessions
 205  
      * @param host       the host name or IP string from where the attempt is occuring
 206  
      * @since 1.0
 207  
      */
 208  
     public UsernamePasswordToken(final String username, final String password,
 209  
                                  final boolean rememberMe, final String host) {
 210  0
         this(username, password != null ? password.toCharArray() : null, rememberMe, host);
 211  0
     }
 212  
 
 213  
     /*--------------------------------------------
 214  
     |  A C C E S S O R S / M O D I F I E R S    |
 215  
     ============================================*/
 216  
 
 217  
     /**
 218  
      * Returns the username submitted during an authentication attempt.
 219  
      *
 220  
      * @return the username submitted during an authentication attempt.
 221  
      */
 222  
     public String getUsername() {
 223  33
         return username;
 224  
     }
 225  
 
 226  
     /**
 227  
      * Sets the username for submission during an authentication attempt.
 228  
      *
 229  
      * @param username the username to be used for submission during an authentication attempt.
 230  
      */
 231  
     public void setUsername(String username) {
 232  0
         this.username = username;
 233  0
     }
 234  
 
 235  
 
 236  
     /**
 237  
      * Returns the password submitted during an authentication attempt as a character array.
 238  
      *
 239  
      * @return the password submitted during an authentication attempt as a character array.
 240  
      */
 241  
     public char[] getPassword() {
 242  36
         return password;
 243  
     }
 244  
 
 245  
     /**
 246  
      * Sets the password for submission during an authentication attempt.
 247  
      *
 248  
      * @param password the password to be used for submission during an authentication attemp.
 249  
      */
 250  
     public void setPassword(char[] password) {
 251  0
         this.password = password;
 252  0
     }
 253  
 
 254  
     /**
 255  
      * Simply returns {@link #getUsername() getUsername()}.
 256  
      *
 257  
      * @return the {@link #getUsername() username}.
 258  
      * @see org.apache.shiro.authc.AuthenticationToken#getPrincipal()
 259  
      */
 260  
     public Object getPrincipal() {
 261  14
         return getUsername();
 262  
     }
 263  
 
 264  
     /**
 265  
      * Returns the {@link #getPassword() password} char array.
 266  
      *
 267  
      * @return the {@link #getPassword() password} char array.
 268  
      * @see org.apache.shiro.authc.AuthenticationToken#getCredentials()
 269  
      */
 270  
     public Object getCredentials() {
 271  36
         return getPassword();
 272  
     }
 273  
 
 274  
     /**
 275  
      * Returns the host name or IP string from where the authentication attempt occurs.  May be <tt>null</tt> if the
 276  
      * host name/IP is unknown or explicitly omitted.  It is up to the Authenticator implementation processing this
 277  
      * token if an authentication attempt without a host is valid or not.
 278  
      * <p/>
 279  
      * <p>(Shiro's default Authenticator allows <tt>null</tt> hosts to support localhost and proxy server environments).</p>
 280  
      *
 281  
      * @return the host from where the authentication attempt occurs, or <tt>null</tt> if it is unknown or
 282  
      *         explicitly omitted.
 283  
      * @since 1.0
 284  
      */
 285  
     public String getHost() {
 286  34
         return host;
 287  
     }
 288  
 
 289  
     /**
 290  
      * Sets the host name or IP string from where the authentication attempt occurs.  It is up to the Authenticator
 291  
      * implementation processing this token if an authentication attempt without a host is valid or not.
 292  
      * <p/>
 293  
      * <p>(Shiro's default Authenticator
 294  
      * allows <tt>null</tt> hosts to allow localhost and proxy server environments).</p>
 295  
      *
 296  
      * @param host the host name or IP string from where the attempt is occuring
 297  
      * @since 1.0
 298  
      */
 299  
     public void setHost(String host) {
 300  0
         this.host = host;
 301  0
     }
 302  
 
 303  
     /**
 304  
      * Returns <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered
 305  
      * across sessions, <tt>false</tt> otherwise.  Unless overridden, this value is <tt>false</tt> by default.
 306  
      *
 307  
      * @return <tt>true</tt> if the submitting user wishes their identity (principal(s)) to be remembered
 308  
      *         across sessions, <tt>false</tt> otherwise (<tt>false</tt> by default).
 309  
      * @since 0.9
 310  
      */
 311  
     public boolean isRememberMe() {
 312  0
         return rememberMe;
 313  
     }
 314  
 
 315  
     /**
 316  
      * Sets if the submitting user wishes their identity (pricipal(s)) to be remembered across sessions.  Unless
 317  
      * overridden, the default value is <tt>false</tt>, indicating <em>not</em> to be remembered across sessions.
 318  
      *
 319  
      * @param rememberMe value inidicating if the user wishes their identity (principal(s)) to be remembered across
 320  
      *                   sessions.
 321  
      * @since 0.9
 322  
      */
 323  
     public void setRememberMe(boolean rememberMe) {
 324  0
         this.rememberMe = rememberMe;
 325  0
     }
 326  
 
 327  
     /*--------------------------------------------
 328  
     |               M E T H O D S               |
 329  
     ============================================*/
 330  
 
 331  
     /**
 332  
      * Clears out (nulls) the username, password, rememberMe, and inetAddress.  The password bytes are explicitly set to
 333  
      * <tt>0x00</tt> before nulling to eliminate the possibility of memory access at a later time.
 334  
      */
 335  
     public void clear() {
 336  0
         this.username = null;
 337  0
         this.host = null;
 338  0
         this.rememberMe = false;
 339  
 
 340  0
         if (this.password != null) {
 341  0
             for (int i = 0; i < password.length; i++) {
 342  0
                 this.password[i] = 0x00;
 343  
             }
 344  0
             this.password = null;
 345  
         }
 346  
 
 347  0
     }
 348  
 
 349  
     /**
 350  
      * Returns the String representation.  It does not include the password in the resulting
 351  
      * string for security reasons to prevent accidentially printing out a password
 352  
      * that might be widely viewable).
 353  
      *
 354  
      * @return the String representation of the <tt>UsernamePasswordToken</tt>, omitting
 355  
      *         the password.
 356  
      */
 357  
     public String toString() {
 358  74
         StringBuilder sb = new StringBuilder();
 359  74
         sb.append(getClass().getName());
 360  74
         sb.append(" - ");
 361  74
         sb.append(username);
 362  74
         sb.append(", rememberMe=").append(rememberMe);
 363  74
         if (host != null) {
 364  5
             sb.append(" (").append(host).append(")");
 365  
         }
 366  74
         return sb.toString();
 367  
     }
 368  
 
 369  
 }