1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.security.spi.impl;
18
19 import java.sql.Timestamp;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Date;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.Set;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.jetspeed.security.AlgorithmUpgradePasswordEncodingService;
30 import org.apache.jetspeed.security.InvalidNewPasswordException;
31 import org.apache.jetspeed.security.InvalidPasswordException;
32 import org.apache.jetspeed.security.PasswordAlreadyUsedException;
33 import org.apache.jetspeed.security.SecurityException;
34 import org.apache.jetspeed.security.om.InternalCredential;
35 import org.apache.jetspeed.security.om.InternalUserPrincipal;
36 import org.apache.jetspeed.security.om.impl.InternalCredentialImpl;
37 import org.apache.jetspeed.security.spi.CredentialHandler;
38 import org.apache.jetspeed.security.spi.AlgorithmUpgradeCredentialPasswordEncoder;
39 import org.apache.jetspeed.security.spi.InternalPasswordCredentialInterceptor;
40 import org.apache.jetspeed.security.spi.PasswordCredentialProvider;
41 import org.apache.jetspeed.security.spi.SecurityAccess;
42
43 /***
44 * @see org.apache.jetspeed.security.spi.CredentialHandler
45 * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
46 */
47 public class DefaultCredentialHandler implements CredentialHandler
48 {
49 private static final Log log = LogFactory.getLog(DefaultCredentialHandler.class);
50
51 private SecurityAccess securityAccess;
52
53 private PasswordCredentialProvider pcProvider;
54
55 private InternalPasswordCredentialInterceptor ipcInterceptor;
56
57 public DefaultCredentialHandler(SecurityAccess securityAccess, PasswordCredentialProvider pcProvider,
58 InternalPasswordCredentialInterceptor ipcInterceptor)
59 {
60 this.securityAccess = securityAccess;
61 this.pcProvider = pcProvider;
62 this.ipcInterceptor = ipcInterceptor;
63 }
64
65 /***
66 * @see org.apache.jetspeed.security.spi.CredentialHandler#getPrivateCredentials(java.lang.String)
67 */
68 public Set getPrivateCredentials(String username)
69 {
70 Set credentials = new HashSet();
71 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(username, false);
72 if (null != internalUser)
73 {
74 InternalCredential credential = getPasswordCredential(internalUser, username );
75 if ( credential != null )
76 {
77 try
78 {
79 credentials.add(pcProvider.create(username,credential));
80 }
81 catch (SecurityException e)
82 {
83 if ( log.isErrorEnabled() )
84 log.error("Failure creating a PasswordCredential for InternalCredential "+credential, e);
85 }
86 }
87 }
88 return credentials;
89 }
90
91 /***
92 * @see org.apache.jetspeed.security.spi.CredentialHandler#getPublicCredentials(java.lang.String)
93 */
94 public Set getPublicCredentials(String username)
95 {
96 return new HashSet();
97 }
98
99 private InternalCredential getPasswordCredential(InternalUserPrincipal internalUser, String username)
100 {
101 InternalCredential credential = null;
102
103 Collection internalCredentials = internalUser.getCredentials();
104 if ( internalCredentials != null )
105 {
106 Iterator iter = internalCredentials.iterator();
107
108 while (iter.hasNext())
109 {
110 credential = (InternalCredential) iter.next();
111 if (credential.getType() == InternalCredential.PRIVATE )
112 {
113 if ((null != credential.getClassname())
114 && (credential.getClassname().equals(pcProvider.getPasswordCredentialClass().getName())))
115 {
116 try
117 {
118 if ( ipcInterceptor != null && ipcInterceptor.afterLoad(pcProvider, username, credential) )
119 {
120
121 securityAccess.setInternalUserPrincipal(internalUser,internalUser.isMappingOnly());
122 }
123 break;
124 }
125 catch (SecurityException e)
126 {
127 if ( log.isErrorEnabled() )
128 log.error("Failure loading InternalCredential "+credential, e);
129 }
130 }
131 }
132 credential = null;
133 }
134 }
135 return credential;
136 }
137
138 /***
139 * @see org.apache.jetspeed.security.spi.CredentialHandler#setPassword(java.lang.String,java.lang.String,java.lang.String)
140 */
141 public void setPassword(String userName, String oldPassword, String newPassword) throws SecurityException
142 {
143 setPassword (userName, oldPassword, newPassword, false);
144 }
145
146 /***
147 * @see org.apache.jetspeed.security.spi.CredentialHandler#importPassword(java.lang.String,java.lang.String)
148 */
149 public void importPassword(String userName, String newPassword) throws SecurityException
150 {
151 setPassword (userName, null, newPassword, true);
152 }
153
154 /***
155 * @see org.apache.jetspeed.security.spi.CredentialHandler#setPassword(java.lang.String,java.lang.String,java.lang.String, boolean)
156 */
157 protected void setPassword(String userName, String oldPassword, String newPassword, boolean raw) throws SecurityException
158 {
159 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(userName, false);
160 if (null == internalUser)
161 {
162 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
163 }
164
165 Collection credentials = internalUser.getCredentials();
166 if (null == credentials)
167 {
168 credentials = new ArrayList();
169 }
170
171 InternalCredential credential = getPasswordCredential(internalUser, userName );
172
173 if (null != oldPassword)
174 {
175 if ( credential != null &&
176 credential.getValue() != null &&
177 credential.isEncoded() &&
178 pcProvider.getEncoder() != null )
179 {
180 if ( pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder )
181 {
182 oldPassword = ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).encode(userName,oldPassword, credential);
183 }
184 else
185 {
186 oldPassword = pcProvider.getEncoder().encode(userName,oldPassword);
187 }
188 }
189 }
190
191 if (oldPassword != null && (credential == null || credential.getValue() == null || !credential.getValue().equals(oldPassword)))
192 {
193
194 throw new InvalidPasswordException();
195 }
196 if (!raw)
197 {
198 if ( pcProvider.getValidator() != null )
199 {
200 try
201 {
202 pcProvider.getValidator().validate(newPassword);
203 }
204 catch (InvalidPasswordException ipe)
205 {
206 throw new InvalidNewPasswordException();
207 }
208 }
209 }
210 boolean encoded = false;
211 if ( pcProvider.getEncoder() != null )
212 {
213 if (!(raw))
214 newPassword = pcProvider.getEncoder().encode(userName, newPassword);
215 encoded = true;
216 }
217
218 boolean create = credential == null;
219
220 if ( create )
221 {
222 credential = new InternalCredentialImpl(internalUser.getPrincipalId(), newPassword, InternalCredential.PRIVATE,
223 pcProvider.getPasswordCredentialClass().getName());
224 credential.setEncoded(encoded);
225 credentials.add(credential);
226 }
227 else if ( oldPassword == null )
228 {
229
230
231
232
233
234 }
235 else if ( oldPassword.equals(newPassword) )
236 {
237 throw new PasswordAlreadyUsedException();
238 }
239
240 if ( ipcInterceptor != null )
241 {
242 if ( create )
243 {
244 ipcInterceptor.beforeCreate(internalUser, credentials, userName, credential, newPassword );
245 }
246 else
247 {
248 ipcInterceptor.beforeSetPassword(internalUser, credentials, userName, credential, newPassword, oldPassword != null );
249 }
250 }
251
252 if (!create)
253 {
254 credential.setValue(newPassword);
255 credential.setEncoded(encoded);
256 credential.setUpdateRequired(false);
257 }
258
259 long time = new Date().getTime();
260
261 if ( oldPassword == null )
262 {
263
264
265 if ( encoded && pcProvider.getEncoder() instanceof AlgorithmUpgradePasswordEncodingService )
266 {
267
268
269
270 credential.setPreviousAuthenticationDate(new Timestamp(new Date().getTime()));
271 credential.setLastAuthenticationDate(null);
272 }
273 }
274 else
275 {
276
277 credential.setPreviousAuthenticationDate(credential.getLastAuthenticationDate());
278 credential.setLastAuthenticationDate(new Timestamp(time));
279 }
280
281 credential.setModifiedDate(new Timestamp(time));
282 internalUser.setModifiedDate(new Timestamp(time));
283 internalUser.setCredentials(credentials);
284
285 securityAccess.setInternalUserPrincipal(internalUser, false);
286 }
287
288
289 /***
290 * @see org.apache.jetspeed.security.spi.CredentialHandler#setPasswordEnabled(java.lang.String, boolean)
291 */
292 public void setPasswordEnabled(String userName, boolean enabled) throws SecurityException
293 {
294 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(userName, false);
295 if (null != internalUser)
296 {
297 InternalCredential credential = getPasswordCredential(internalUser, userName );
298 if ( credential != null && !credential.isExpired() && credential.isEnabled() != enabled )
299 {
300 long time = new Date().getTime();
301 credential.setEnabled(enabled);
302 credential.setAuthenticationFailures(0);
303 credential.setModifiedDate(new Timestamp(time));
304 internalUser.setModifiedDate(new Timestamp(time));
305 securityAccess.setInternalUserPrincipal(internalUser, false);
306 }
307 }
308 else
309 {
310 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
311 }
312 }
313
314 /***
315 * @see org.apache.jetspeed.security.spi.CredentialHandler#setPasswordUpdateRequired(java.lang.String, boolean)
316 */
317 public void setPasswordUpdateRequired(String userName, boolean updateRequired) throws SecurityException
318 {
319 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(userName, false);
320 if (null != internalUser)
321 {
322 InternalCredential credential = getPasswordCredential(internalUser, userName );
323 if ( credential != null && !credential.isExpired() && credential.isUpdateRequired() != updateRequired )
324 {
325
326 if ( !updateRequired && !credential.isEncoded() && pcProvider.getValidator() != null )
327 {
328 pcProvider.getValidator().validate(credential.getValue());
329 }
330 credential.setUpdateRequired(updateRequired);
331 long time = new Date().getTime();
332 credential.setModifiedDate(new Timestamp(time));
333
334
335
336
337 credential.setPreviousAuthenticationDate(new Timestamp(time));
338 credential.setModifiedDate(new Timestamp(time));
339 internalUser.setModifiedDate(new Timestamp(time));
340 securityAccess.setInternalUserPrincipal(internalUser, false);
341 }
342 }
343 else
344 {
345 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
346 }
347 }
348
349 /***
350 * @see org.apache.jetspeed.security.spi.CredentialHandler#setPasswordExpiration(java.lang.String, java.sql.Date)
351 */
352 public void setPasswordExpiration(String userName, java.sql.Date expirationDate) throws SecurityException
353 {
354 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(userName, false);
355 if (null != internalUser)
356 {
357 InternalCredential credential = getPasswordCredential(internalUser, userName );
358 if ( credential != null )
359 {
360 long time = new Date().getTime();
361 if ( expirationDate != null && new java.sql.Date(time).after(expirationDate))
362 {
363 credential.setExpired(true);
364 }
365 else
366 {
367 credential.setExpired(false);
368 }
369 credential.setExpirationDate(expirationDate);
370
371 credential.setModifiedDate(new Timestamp(time));
372 internalUser.setModifiedDate(new Timestamp(time));
373 securityAccess.setInternalUserPrincipal(internalUser, false);
374 }
375 }
376 else
377 {
378 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
379 }
380 }
381
382 /***
383 * @see org.apache.jetspeed.security.spi.CredentialHandler#authenticate(java.lang.String, java.lang.String)
384 */
385 public boolean authenticate(String userName, String password) throws SecurityException
386 {
387 boolean authenticated = false;
388 InternalUserPrincipal internalUser = securityAccess.getInternalUserPrincipal(userName, false);
389 if (null != internalUser)
390 {
391 InternalCredential credential = getPasswordCredential(internalUser, userName );
392 if ( credential != null && credential.isEnabled() && !credential.isExpired())
393 {
394 String encodedPassword = password;
395 if ( pcProvider.getEncoder() != null && credential.isEncoded())
396 {
397 if ( pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder )
398 {
399 encodedPassword = ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).encode(userName,password, credential);
400 }
401 else
402 {
403 encodedPassword = pcProvider.getEncoder().encode(userName,password);
404 }
405 }
406
407 authenticated = credential.getValue().equals(encodedPassword);
408 boolean update = false;
409
410 if ( ipcInterceptor != null )
411 {
412 update = ipcInterceptor.afterAuthenticated(internalUser, userName, credential, authenticated);
413 if ( update && (!credential.isEnabled() || credential.isExpired()))
414 {
415 authenticated = false;
416 }
417 }
418 long time = new Date().getTime();
419
420 if ( authenticated )
421 {
422 credential.setAuthenticationFailures(0);
423
424 if ( pcProvider.getEncoder() != null && pcProvider.getEncoder() instanceof AlgorithmUpgradeCredentialPasswordEncoder)
425 {
426 ((AlgorithmUpgradeCredentialPasswordEncoder)pcProvider.getEncoder()).recodeIfNeeded(userName,password,credential);
427 }
428
429 credential.setPreviousAuthenticationDate(credential.getLastAuthenticationDate());
430 credential.setLastAuthenticationDate(new Timestamp(time));
431 update = true;
432 }
433
434 if ( update )
435 {
436 credential.setModifiedDate(new Timestamp(time));
437 internalUser.setModifiedDate(new Timestamp(time));
438 securityAccess.setInternalUserPrincipal(internalUser, false);
439 }
440 }
441 }
442 else
443 {
444 throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(userName));
445 }
446 return authenticated;
447 }
448 }