1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.idp.util;
18
19 import java.util.UUID;
20
21 import javax.servlet.ServletContext;
22 import javax.servlet.http.Cookie;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.opensaml.saml2.metadata.EntityDescriptor;
27 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
28 import org.opensaml.util.storage.StorageService;
29 import org.opensaml.xml.util.DatatypeHelper;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import edu.internet2.middleware.shibboleth.common.attribute.filtering.AttributeFilteringEngine;
34 import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML1AttributeAuthority;
35 import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML2AttributeAuthority;
36 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolver;
37 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager;
38 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
39 import edu.internet2.middleware.shibboleth.common.session.SessionManager;
40 import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
41 import edu.internet2.middleware.shibboleth.idp.authn.LoginContextEntry;
42 import edu.internet2.middleware.shibboleth.idp.profile.IdPProfileHandlerManager;
43 import edu.internet2.middleware.shibboleth.idp.session.Session;
44
45
46 public class HttpServletHelper {
47
48
49 public static final String IDP_SESSION_COOKIE = "_idp_session";
50
51
52 public static final String LOGIN_CTX_KEY_NAME = "_idp_authn_lc_key";
53
54
55 public static final String ATTRIBUTE_FILTER_ENGINE_SID_CTX_PARAM = "AttributeFilterEngineId";
56
57
58 public static final String ATTRIBUTE_RESOLVER_SID_CTX_PARAM = "AttributeResolverId";
59
60
61
62
63
64 public static final String LOGIN_CTX_PARTITION_CTX_PARAM = "loginContextPartitionName";
65
66
67 public static final String PROFILE_HANDLER_MNGR_SID_CTX_PARAM = "ProfileHandlerMngrId";
68
69
70
71
72
73 public static final String RP_CONFIG_MNGR_SID_CTX_PARAM = "RelyingPartyConfigurationManagerId";
74
75
76 public static final String SAML1_AA_SID_CTX_PARAM = "SAML1AttributeAuthorityId";
77
78
79 public static final String SAML2_AA_SID_CTX_PARAM = "SAML2AttributeAuthorityId";
80
81
82 public static final String SESSION_MNGR_SID_CTX_PARAM = "SessionManagerId";
83
84
85 public static final String STORAGE_SERVICE_SID_CTX_PARAM = "StorageServiceId";
86
87
88 public static final String DEFAULT_ATTRIBUTE_FILTER_ENGINE_SID = "shibboleth.AttributeFilterEngine";
89
90
91 public static final String DEFAULT_ATTRIBUTE_RESOLVER_SID = "shibboleth.AttributeResolver";
92
93
94 public static final String DEFAULT_LOGIN_CTX_PARITION = "loginContexts";
95
96
97 public static final String DEFAULT_PROFILE_HANDLER_MNGR_SID = "shibboleth.HandlerManager";
98
99
100 public static final String DEFAULT_RP_CONFIG_MNGR_SID = "shibboleth.RelyingPartyConfigurationManager";
101
102
103 public static final String DEFAULT_SAML1_AA_SID = "shibboleth.SAML1AttributeAuthority";
104
105
106 public static final String DEFAULT_SAML2_AA_SID = "shibboleth.SAML2AttributeAuthority";
107
108
109 public static final String DEFAULT_SESSION_MNGR_SID = "shibboleth.SessionManager";
110
111
112 public static final String DEFAULT_STORAGE_SERVICE_SID = "shibboleth.StorageService";
113
114
115 private static final Logger log = LoggerFactory.getLogger(HttpServletHelper.class);
116
117
118
119
120
121
122
123 public static void bindLoginContext(LoginContext loginContext, HttpServletRequest httpRequest) {
124 if (httpRequest == null) {
125 throw new IllegalArgumentException("HTTP request may not be null");
126 }
127 httpRequest.setAttribute(LOGIN_CTX_KEY_NAME, loginContext);
128 }
129
130
131
132
133
134
135
136
137
138
139
140 public static void bindLoginContext(LoginContext loginContext, StorageService storageService,
141 ServletContext context, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
142 if (storageService == null) {
143 throw new IllegalArgumentException("Storage service may not be null");
144 }
145 if (httpRequest == null) {
146 throw new IllegalArgumentException("HTTP request may not be null");
147 }
148 if (loginContext == null) {
149 return;
150 }
151
152 bindLoginContext(loginContext, httpRequest);
153
154 String parition = getContextParam(context, LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION);
155 log.debug("LoginContext parition: {}", parition);
156
157 String contextKey = UUID.randomUUID().toString();
158 while (storageService.contains(parition, contextKey)) {
159 contextKey = UUID.randomUUID().toString();
160 }
161 log.debug("LoginContext key: {}", contextKey);
162
163 LoginContextEntry entry = new LoginContextEntry(loginContext, 1800000);
164 storageService.put(parition, contextKey, entry);
165
166 Cookie contextKeyCookie = new Cookie(LOGIN_CTX_KEY_NAME, contextKey);
167 contextKeyCookie.setVersion(1);
168 contextKeyCookie.setPath("".equals(httpRequest.getContextPath()) ? "/" : httpRequest.getContextPath());
169 contextKeyCookie.setSecure(httpRequest.isSecure());
170 httpResponse.addCookie(contextKeyCookie);
171 }
172
173
174
175
176
177
178
179
180 public static AttributeFilteringEngine<?> getAttributeFilterEnginer(ServletContext context) {
181 return getAttributeFilterEnginer(context, getContextParam(context, ATTRIBUTE_FILTER_ENGINE_SID_CTX_PARAM,
182 DEFAULT_ATTRIBUTE_FILTER_ENGINE_SID));
183 }
184
185
186
187
188
189
190
191
192
193 public static AttributeFilteringEngine<?> getAttributeFilterEnginer(ServletContext context, String serviceId) {
194 return (AttributeFilteringEngine<?>) context.getAttribute(serviceId);
195 }
196
197
198
199
200
201
202
203
204 public static AttributeResolver<?> getAttributeResolver(ServletContext context) {
205 return getAttributeResolver(context, getContextParam(context, ATTRIBUTE_RESOLVER_SID_CTX_PARAM,
206 DEFAULT_ATTRIBUTE_RESOLVER_SID));
207 }
208
209
210
211
212
213
214
215
216
217 public static AttributeResolver<?> getAttributeResolver(ServletContext context, String serviceId) {
218 return (AttributeResolver<?>) context.getAttribute(serviceId);
219 }
220
221
222
223
224
225
226
227
228
229
230
231 public static String getContextParam(ServletContext context, String name, String defaultValue) {
232 String value = DatatypeHelper.safeTrimOrNullString(context.getInitParameter(name));
233 if (value == null) {
234 value = defaultValue;
235 }
236 return value;
237 }
238
239
240
241
242
243
244
245
246
247 public static Cookie getCookie(HttpServletRequest httpRequest, String cookieName) {
248 Cookie[] requestCookies = httpRequest.getCookies();
249 if (requestCookies != null) {
250 for (Cookie requestCookie : requestCookies) {
251 if (requestCookie != null && DatatypeHelper.safeEquals(requestCookie.getName(), cookieName)) {
252 return requestCookie;
253 }
254 }
255 }
256
257 return null;
258 }
259
260
261
262
263
264
265
266
267
268 public static LoginContext getLoginContext(HttpServletRequest httpRequest) {
269 return (LoginContext) httpRequest.getAttribute(LOGIN_CTX_KEY_NAME);
270 }
271
272
273
274
275
276
277
278
279
280
281
282 public static LoginContext getLoginContext(StorageService storageService, ServletContext context,
283 HttpServletRequest httpRequest) {
284 if (storageService == null) {
285 throw new IllegalArgumentException("Storage service may not be null");
286 }
287 if (context == null) {
288 throw new IllegalArgumentException("Servlet context may not be null");
289 }
290 if (httpRequest == null) {
291 throw new IllegalArgumentException("HTTP request may not be null");
292 }
293
294 LoginContext loginContext = getLoginContext(httpRequest);
295 if (loginContext == null) {
296 log.debug("LoginContext not bound to HTTP request, retrieving it from storage service");
297 Cookie loginContextKeyCookie = getCookie(httpRequest, LOGIN_CTX_KEY_NAME);
298 if (loginContextKeyCookie == null) {
299 log.debug("LoginContext key cookie was not present in request");
300 return null;
301 }
302
303 String loginContextKey = DatatypeHelper.safeTrimOrNullString(loginContextKeyCookie.getValue());
304 if (loginContextKey == null) {
305 log.warn("Corrupted LoginContext Key cookie, it did not contain a value");
306 }
307 log.debug("LoginContext key is '{}'", loginContextKey);
308
309 String partition = getContextParam(context, LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION);
310 log.debug("parition: {}", partition);
311 LoginContextEntry entry = (LoginContextEntry) storageService.get(partition, loginContextKey);
312 if (entry != null) {
313 if (entry.isExpired()) {
314 log.debug("LoginContext found but it was expired");
315 } else {
316 loginContext = entry.getLoginContext();
317 }
318 } else {
319 log.debug("No login context in storage service");
320 }
321 }
322
323 return loginContext;
324 }
325
326
327
328
329
330
331
332
333 public static IdPProfileHandlerManager getProfileHandlerManager(ServletContext context) {
334 return getProfileHandlerManager(context, getContextParam(context, PROFILE_HANDLER_MNGR_SID_CTX_PARAM,
335 DEFAULT_PROFILE_HANDLER_MNGR_SID));
336 }
337
338
339
340
341
342
343
344
345
346 public static IdPProfileHandlerManager getProfileHandlerManager(ServletContext context, String serviceId) {
347 return (IdPProfileHandlerManager) context.getAttribute(serviceId);
348 }
349
350
351
352
353
354
355
356
357 public static RelyingPartyConfigurationManager getRelyingPartyConfirmationManager(ServletContext context) {
358 return getRelyingPartyConfirmationManager(context, getContextParam(context, RP_CONFIG_MNGR_SID_CTX_PARAM,
359 DEFAULT_RP_CONFIG_MNGR_SID));
360 }
361
362
363
364
365
366
367
368
369
370 public static RelyingPartyConfigurationManager getRelyingPartyConfirmationManager(ServletContext context,
371 String serviceId) {
372 return (RelyingPartyConfigurationManager) context.getAttribute(serviceId);
373 }
374
375
376
377
378
379
380
381
382
383 public static EntityDescriptor getRelyingPartyMetadata(String relyingPartyEntityId,
384 RelyingPartyConfigurationManager rpConfigMngr) {
385 if (rpConfigMngr instanceof SAMLMDRelyingPartyConfigurationManager) {
386 SAMLMDRelyingPartyConfigurationManager samlRpConfigMngr = (SAMLMDRelyingPartyConfigurationManager) rpConfigMngr;
387 try {
388 return samlRpConfigMngr.getMetadataProvider().getEntityDescriptor(relyingPartyEntityId);
389 } catch (MetadataProviderException e) {
390
391 }
392 }
393
394 return null;
395 }
396
397
398
399
400
401
402
403
404 public static SAML1AttributeAuthority getSAML1AttributeAuthority(ServletContext context) {
405 return getSAML1AttributeAuthority(context, getContextParam(context, SAML1_AA_SID_CTX_PARAM,
406 DEFAULT_SAML1_AA_SID));
407 }
408
409
410
411
412
413
414
415
416
417 public static SAML1AttributeAuthority getSAML1AttributeAuthority(ServletContext context, String serviceId) {
418 return (SAML1AttributeAuthority) context.getAttribute(serviceId);
419 }
420
421
422
423
424
425
426
427
428 public static SAML2AttributeAuthority getSAML2AttributeAuthority(ServletContext context) {
429 return getSAML2AttributeAuthority(context, getContextParam(context, SAML2_AA_SID_CTX_PARAM,
430 DEFAULT_SAML2_AA_SID));
431 }
432
433
434
435
436
437
438
439
440
441 public static SAML2AttributeAuthority getSAML2AttributeAuthority(ServletContext context, String serviceId) {
442 return (SAML2AttributeAuthority) context.getAttribute(serviceId);
443 }
444
445
446
447
448
449
450
451
452 public static SessionManager<Session> getSessionManager(ServletContext context) {
453 return getSessionManager(context,
454 getContextParam(context, SESSION_MNGR_SID_CTX_PARAM, DEFAULT_SESSION_MNGR_SID));
455 }
456
457
458
459
460
461
462
463
464
465 public static SessionManager<Session> getSessionManager(ServletContext context, String serviceId) {
466 return (SessionManager<Session>) context.getAttribute(serviceId);
467 }
468
469
470
471
472
473
474
475
476 public static StorageService<?, ?> getStorageService(ServletContext context) {
477 return getStorageService(context, getContextParam(context, STORAGE_SERVICE_SID_CTX_PARAM,
478 DEFAULT_STORAGE_SERVICE_SID));
479 }
480
481
482
483
484
485
486
487
488
489 public static StorageService<?, ?> getStorageService(ServletContext context, String serviceId) {
490 return (StorageService<?, ?>) context.getAttribute(serviceId);
491 }
492
493
494
495
496
497
498
499
500
501 public static Session getUserSession(HttpServletRequest httpRequest) {
502 return (Session) httpRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516 public static LoginContext unbindLoginContext(StorageService storageService, ServletContext context,
517 HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
518 if (storageService == null || context == null || httpRequest == null || httpResponse == null) {
519 return null;
520 }
521
522 Cookie loginContextKeyCookie = getCookie(httpRequest, LOGIN_CTX_KEY_NAME);
523 if (loginContextKeyCookie == null) {
524 return null;
525 }
526
527 String loginContextKey = DatatypeHelper.safeTrimOrNullString(loginContextKeyCookie.getValue());
528 if (loginContextKey == null) {
529 log.warn("Corrupted LoginContext Key cookie, it did not contain a value");
530 }
531
532 httpRequest.setAttribute(LOGIN_CTX_KEY_NAME, null);
533 loginContextKeyCookie.setMaxAge(0);
534 loginContextKeyCookie.setPath("".equals(httpRequest.getContextPath()) ? "/" : httpRequest.getContextPath());
535 loginContextKeyCookie.setVersion(1);
536 httpResponse.addCookie(loginContextKeyCookie);
537
538 LoginContextEntry entry = (LoginContextEntry) storageService.remove(getContextParam(context,
539 LOGIN_CTX_PARTITION_CTX_PARAM, DEFAULT_LOGIN_CTX_PARITION), loginContextKey);
540 if (entry != null && !entry.isExpired()) {
541 return entry.getLoginContext();
542 }
543 return null;
544 }
545 }