Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
UsernamePasswordToken |
|
| 1.3333333333333333;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 | * "Remember Me" 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>"Remember Me" 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 | } |