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