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