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