1 /*
2 * Copyright 2006 University Corporation for Advanced Internet Development, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package edu.internet2.middleware.shibboleth.idp.authn;
18
19 import java.io.Serializable;
20 import java.security.Principal;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.joda.time.DateTime;
26 import org.opensaml.xml.util.LazyList;
27
28 import edu.internet2.middleware.shibboleth.idp.session.AuthenticationMethodInformation;
29
30 /**
31 * Login context created by a profile handler and interpreted by the authentication package.
32 *
33 * Two properties are tracked by default:
34 * <ul>
35 * <li><code>forceAuth</code> - Should user authentication be forced (default value: false).</li>
36 * <li><code>passiveAuth</code> - Should user authentication not control the UI (default value: false).</li>
37 * </ul>
38 *
39 * A {@link Map}<String, Object> is provided to store other properties. Alternatively, a profile handler may
40 * create a subclass of LoginContext with extra fields.
41 *
42 * LoginContexts should be created by a profile handler when authentication is needed. Once control has returned to the
43 * profile handler, it should remove the LoginContext from the HttpSession.
44 *
45 * The {@link AuthenticationEngine} should set the {@link LoginContext#setAuthenticationAttempted()},
46 * {@link LoginContext#setPrincipalAuthenticated(boolean)},
47 * {@link LoginContext#setAuthenticationFailure(AuthenticationException)}, appropriately.
48 */
49 public class LoginContext implements Serializable {
50
51 /** the key in a HttpSession where login contexts are stored. */
52 public static final String LOGIN_CONTEXT_KEY = "shib2.logincontext";
53
54 /** Serial version UID. */
55 private static final long serialVersionUID = -8764003758734956911L;
56
57 /** Entity ID of the relying party. */
58 private String relyingPartyId;
59
60 /** Should user authentication be forced. */
61 private boolean forceAuth;
62
63 /** Must authentication not interact with the UI. */
64 private boolean passiveAuth;
65
66 /** A catch-all map for other properties. */
67 private Map<String, Serializable> propsMap = new ConcurrentHashMap<String, Serializable>(0);
68
69 /** The ProfileHandler URL. */
70 private String profileHandlerURL;
71
72 /** The authentication engine's URL. */
73 private String authnEngineURL;
74
75 /** Whether authentication been attempted yet. */
76 private boolean authnAttempted;
77
78 /** Attempted user authentication method. */
79 private String attemptedAuthnMethod;
80
81 /** Did authentication succeed? */
82 private boolean principalAuthenticated;
83
84 /** Exception that occurred during authentication. */
85 private AuthenticationException authnException;
86
87 /** The session id. */
88 private String sessionID;
89
90 /** Default authentication method to use if no other method is requested. */
91 private String defaultAuthenticationMethod;
92
93 /** List of request authentication methods. */
94 private List<String> requestAuthenticationMethods;
95
96 /** Information about the authentication method. */
97 private AuthenticationMethodInformation authenticationMethodInformation;
98
99 /** Creates a new instance of LoginContext. */
100 public LoginContext() {
101 requestAuthenticationMethods = new LazyList<String>();
102 }
103
104 /**
105 * Creates a new instance of LoginContext.
106 *
107 * @param force if the authentication manager must re-authenticate the user.
108 * @param passive if the authentication manager must not interact with the users UI.
109 */
110 public LoginContext(boolean force, boolean passive) {
111 forceAuth = force;
112 passiveAuth = passive;
113 requestAuthenticationMethods = new LazyList<String>();
114 }
115
116 /**
117 * Gets the authentication method that was used when attempting to authenticate the user. Note, this may be
118 * different than the authentication method reported within {@link #getAuthenticationMethodInformation()}.
119 *
120 * @return authentication method that was used when attempting to authenticate the user
121 */
122 public synchronized String getAttemptedAuthnMethod() {
123 return attemptedAuthnMethod;
124 }
125
126 /**
127 * Returns if authentication has been attempted for this user.
128 *
129 * @return if authentication has been attempted for this user
130 */
131 public synchronized boolean getAuthenticationAttempted() {
132 return authnAttempted;
133 }
134
135 /**
136 * Gets the duration of authentication.
137 *
138 * @return The duration of authentication, or zero if none was set.
139 */
140 public synchronized long getAuthenticationDuration() {
141 if(authenticationMethodInformation == null){
142 return 0;
143 }
144
145 return authenticationMethodInformation.getAuthenticationDuration();
146 }
147
148 /**
149 * Gets the authentication engine's URL.
150 *
151 * @return the URL of the authentication engine
152 */
153 public synchronized String getAuthenticationEngineURL() {
154 return authnEngineURL;
155 }
156
157 /**
158 * Gets the error that occurred during authentication.
159 *
160 * @return error that occurred during authentication
161 */
162 public synchronized AuthenticationException getAuthenticationFailure() {
163 return authnException;
164 }
165
166 /**
167 * Gets the authentication instant.
168 *
169 * @return The instant of authentication, or <code>null</code> if none was set.
170 */
171 public synchronized DateTime getAuthenticationInstant() {
172 if(authenticationMethodInformation == null){
173 return null;
174 }
175
176 return authenticationMethodInformation.getAuthenticationInstant();
177 }
178
179 /**
180 * Gets the method used to authenticate the user.
181 *
182 * @return The method used to authenticate the user.
183 */
184 public synchronized String getAuthenticationMethod() {
185 if(authenticationMethodInformation == null){
186 return null;
187 }
188 return authenticationMethodInformation.getAuthenticationMethod();
189 }
190
191 /**
192 * Gets information about the authentication event.
193 *
194 * @return information about the authentication event.
195 */
196 public synchronized AuthenticationMethodInformation getAuthenticationMethodInformation() {
197 return authenticationMethodInformation;
198 }
199
200 /**
201 * Gets the authentication method to use if none is requested.
202 *
203 * @return authentication method to use if none is requested, may be null which indicates any method may be used
204 */
205 public synchronized String getDefaultAuthenticationMethod() {
206 return defaultAuthenticationMethod;
207 }
208
209 /**
210 * Returns the ID of the authenticated user.
211 *
212 * @return the ID of the user, or <code>null</code> if authentication failed.
213 */
214 public synchronized String getPrincipalName() {
215 if(authenticationMethodInformation == null){
216 return null;
217 }
218
219 Principal principal = authenticationMethodInformation.getAuthenticationPrincipal();
220 if(principal == null){
221 return null;
222 }
223
224 return principal.getName();
225 }
226
227 /**
228 * Gets the ProfileHandler URL.
229 *
230 * @return the URL of the profile handler that is invoking the Authentication Manager.
231 */
232 public synchronized String getProfileHandlerURL() {
233 return profileHandlerURL;
234 }
235
236 /**
237 * Get an optional property object.
238 *
239 * @param key The key in the properties Map.
240 *
241 * @return The object, or <code>null</code> is no object exists for the key.
242 */
243 public synchronized Object getProperty(String key) {
244 return propsMap.get(key);
245 }
246
247 /**
248 * Gets the entity ID of the relying party.
249 *
250 * @return entity ID of the relying party
251 */
252 public synchronized String getRelyingPartyId() {
253 return relyingPartyId;
254 }
255
256 /**
257 * Return the acceptable authentication handler URIs, in preference order, for authenticating this user. If no
258 * authentication methods are preferred the resultant list will be empty.
259 *
260 * @return an list of authentication method identifiers
261 */
262 public synchronized List<String> getRequestedAuthenticationMethods() {
263 return requestAuthenticationMethods;
264 }
265
266 /**
267 * Gets the {@link edu.internet2.middleware.shibboleth.idp.session.Session} ID.
268 *
269 * @return the Session id
270 */
271 public synchronized String getSessionID() {
272 return sessionID;
273 }
274
275 /**
276 * Returns if authentication must be forced.
277 *
278 * @return <code>true</code> if the authentication manager must re-authenticate the user.
279 */
280 public synchronized boolean isForceAuthRequired() {
281 return forceAuth;
282 }
283
284 /**
285 * Returns if authentication must be passive.
286 *
287 * @return <code>true</code> if the authentication manager must not interact with the users UI.
288 */
289 public synchronized boolean isPassiveAuthRequired() {
290 return passiveAuth;
291 }
292
293 /**
294 * Returns if authentication succeeded.
295 *
296 * @return <code>true</code> is the user was successfully authenticated.
297 */
298 public synchronized boolean isPrincipalAuthenticated() {
299 return principalAuthenticated;
300 }
301
302 /**
303 * Sets the authentication method that was used when attempting to authenticate the user.
304 *
305 * @param method authentication method that was used when attempting to authenticate the user
306 */
307 public synchronized void setAttemptedAuthnMethod(String method) {
308 attemptedAuthnMethod = method;
309 }
310
311 /**
312 * Set if authentication has been attempted.
313 *
314 * This method should be called by an {@link LoginHandler} while processing a request.
315 */
316 public synchronized void setAuthenticationAttempted() {
317 authnAttempted = true;
318 }
319
320 /**
321 * Sets the duration of authentication.
322 *
323 * @param duration The duration of authentication.
324 *
325 * @deprecated this information is contained in the {@link AuthenticationMethodInformation}
326 */
327 public synchronized void setAuthenticationDuration(long duration) {
328 }
329
330 /**
331 * Sets the authentication engine's URL.
332 *
333 * @param url the URL of the authentication engine
334 */
335 public synchronized void setAuthenticationEngineURL(String url) {
336 authnEngineURL = url;
337 }
338
339 /**
340 * Sets the error that occurred during authentication.
341 *
342 * @param error error that occurred during authentication
343 */
344 public synchronized void setAuthenticationFailure(AuthenticationException error) {
345 authnException = error;
346 }
347
348 /**
349 * Sets the authentication instant.
350 *
351 * @param instant The instant of authentication.
352 *
353 * @deprecated this information is contained in the {@link AuthenticationMethodInformation}
354 */
355 public synchronized void setAuthenticationInstant(final DateTime instant) {
356 }
357
358 /**
359 * Sets the method used to authenticate the user.
360 *
361 * @param method The method used to authenticate the user.
362 *
363 * @deprecated this information is contained in the {@link AuthenticationMethodInformation}
364 */
365 public synchronized void setAuthenticationMethod(String method) {
366 }
367
368 /**
369 * Sets the information about the authentication event.
370 *
371 * @param info information about the authentication event
372 */
373 public synchronized void setAuthenticationMethodInformation(AuthenticationMethodInformation info) {
374 authenticationMethodInformation = info;
375 }
376
377 /**
378 * Sets the authentication method to use if none is requested.
379 *
380 * @param method authentication method to use if none is requested, may be null which indicates any method may be
381 * used
382 */
383 public synchronized void setDefaultAuthenticationMethod(String method) {
384 defaultAuthenticationMethod = method;
385 }
386
387 /**
388 * Sets if authentication must be forced.
389 *
390 * @param force if the authentication manager must re-authenticate the user.
391 */
392 public synchronized void setForceAuthRequired(boolean force) {
393 forceAuth = force;
394 }
395
396 /**
397 * Sets if authentication must be passive.
398 *
399 * @param passive if the authentication manager must not interact with the users UI.
400 */
401 public synchronized void setPassiveAuthRequired(boolean passive) {
402 passiveAuth = passive;
403 }
404
405 /**
406 * Sets if authentication succeeded.
407 *
408 * @param authnOK if authentication succeeded;
409 */
410 public synchronized void setPrincipalAuthenticated(boolean authnOK) {
411 this.principalAuthenticated = authnOK;
412 }
413
414 /**
415 * Sets the ID of the authenticated user.
416 *
417 * @param id The userid.
418 *
419 * @deprecated this information is contained in the {@link AuthenticationMethodInformation}
420 */
421 public synchronized void setPrincipalName(String id) {
422
423 }
424
425 /**
426 * Sets the ProfileHandler URL.
427 *
428 * @param url The URL of the profile handler that invoked the AuthenticationManager/
429 */
430 public synchronized void setProfileHandlerURL(String url) {
431 profileHandlerURL = url;
432 }
433
434 /**
435 * Sets an optional property object.
436 *
437 * If an object is already associated with key, it will be overwritten.
438 *
439 * @param key The key to set.
440 * @param obj The object to associate with key.
441 */
442 public synchronized void setProperty(String key, final Serializable obj) {
443 propsMap.put(key, obj);
444 }
445
446 /**
447 * Gets the entity ID of the relying party.
448 *
449 * @param id entity ID of the relying party
450 */
451 public synchronized void setRelyingParty(String id) {
452 relyingPartyId = id;
453 }
454
455 /**
456 * Sets the {@link edu.internet2.middleware.shibboleth.idp.session.Session} ID.
457 *
458 * @param id the Session ID
459 */
460 public synchronized void setSessionID(String id) {
461 sessionID = id;
462 }
463 }