1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.idp.profile;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import javax.servlet.http.HttpServletRequest;
27
28 import org.opensaml.common.IdentifierGenerator;
29 import org.opensaml.common.binding.decoding.SAMLMessageDecoder;
30 import org.opensaml.common.binding.encoding.SAMLMessageEncoder;
31 import org.opensaml.saml1.core.NameIdentifier;
32 import org.opensaml.saml2.metadata.AttributeAuthorityDescriptor;
33 import org.opensaml.saml2.metadata.AuthnAuthorityDescriptor;
34 import org.opensaml.saml2.metadata.Endpoint;
35 import org.opensaml.saml2.metadata.EntityDescriptor;
36 import org.opensaml.saml2.metadata.NameIDFormat;
37 import org.opensaml.saml2.metadata.PDPDescriptor;
38 import org.opensaml.saml2.metadata.RoleDescriptor;
39 import org.opensaml.saml2.metadata.SSODescriptor;
40 import org.opensaml.saml2.metadata.provider.MetadataProvider;
41 import org.opensaml.saml2.metadata.provider.MetadataProviderException;
42 import org.opensaml.security.MetadataCredentialResolver;
43 import org.opensaml.security.MetadataCredentialResolverFactory;
44 import org.opensaml.ws.message.encoder.MessageEncodingException;
45 import org.opensaml.ws.security.SecurityPolicyResolver;
46 import org.opensaml.ws.transport.InTransport;
47 import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
48 import org.opensaml.xml.security.credential.Credential;
49 import org.opensaml.xml.util.DatatypeHelper;
50 import org.opensaml.xml.util.Pair;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
55 import edu.internet2.middleware.shibboleth.common.attribute.encoding.AttributeEncoder;
56 import edu.internet2.middleware.shibboleth.common.attribute.encoding.SAMLNameIdentifierEncoder;
57 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
58 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
59 import edu.internet2.middleware.shibboleth.common.profile.provider.AbstractShibbolethProfileHandler;
60 import edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext;
61 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
62 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartySecurityPolicyResolver;
63 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.AbstractSAMLProfileConfiguration;
64 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.CryptoOperationRequirementLevel;
65 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
66 import edu.internet2.middleware.shibboleth.idp.session.Session;
67
68
69
70
71 public abstract class AbstractSAMLProfileHandler extends
72 AbstractShibbolethProfileHandler<SAMLMDRelyingPartyConfigurationManager, Session> {
73
74
75 private final Logger auditLog = LoggerFactory.getLogger(AuditLogEntry.AUDIT_LOGGER_NAME);
76
77
78 private final Logger log = LoggerFactory.getLogger(AbstractSAMLProfileHandler.class);
79
80
81 private IdentifierGenerator idGenerator;
82
83
84 private Map<String, SAMLMessageDecoder> messageDecoders;
85
86
87 private Map<String, SAMLMessageEncoder> messageEncoders;
88
89
90 private String inboundBinding;
91
92
93 private List<String> supportedOutboundBindings;
94
95
96 private SecurityPolicyResolver securityPolicyResolver;
97
98
99 private MetadataCredentialResolver metadataCredentialResolver;
100
101
102 protected AbstractSAMLProfileHandler() {
103 super();
104 }
105
106
107
108
109
110
111 public SecurityPolicyResolver getSecurityPolicyResolver() {
112 if (securityPolicyResolver == null) {
113 setSecurityPolicyResolver(new RelyingPartySecurityPolicyResolver(getRelyingPartyConfigurationManager()));
114 }
115
116 return securityPolicyResolver;
117 }
118
119
120
121
122
123
124 public void setSecurityPolicyResolver(SecurityPolicyResolver resolver) {
125 securityPolicyResolver = resolver;
126 }
127
128
129
130
131
132
133 protected Logger getAduitLog() {
134 return auditLog;
135 }
136
137
138
139
140
141
142 public IdentifierGenerator getIdGenerator() {
143 return idGenerator;
144 }
145
146
147
148
149
150
151 public String getInboundBinding() {
152 return inboundBinding;
153 }
154
155
156
157
158
159
160 public Map<String, SAMLMessageDecoder> getMessageDecoders() {
161 return messageDecoders;
162 }
163
164
165
166
167
168
169 public Map<String, SAMLMessageEncoder> getMessageEncoders() {
170 return messageEncoders;
171 }
172
173
174
175
176
177
178 public MetadataProvider getMetadataProvider() {
179 SAMLMDRelyingPartyConfigurationManager rpcManager = getRelyingPartyConfigurationManager();
180 if (rpcManager != null) {
181 return rpcManager.getMetadataProvider();
182 }
183
184 return null;
185 }
186
187
188
189
190
191
192 public MetadataCredentialResolver getMetadataCredentialResolver() {
193
194
195 synchronized (this) {
196 if (metadataCredentialResolver == null) {
197 MetadataCredentialResolverFactory mcrFactory = MetadataCredentialResolverFactory.getFactory();
198 MetadataProvider metadataProvider = getMetadataProvider();
199 metadataCredentialResolver = mcrFactory.getInstance(metadataProvider);
200 }
201 }
202 return metadataCredentialResolver;
203 }
204
205
206
207
208
209
210 public List<String> getSupportedOutboundBindings() {
211 return supportedOutboundBindings;
212 }
213
214
215
216
217
218
219
220
221 protected Session getUserSession(InTransport inTransport) {
222 HttpServletRequest rawRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
223 return (Session) rawRequest.getAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE);
224 }
225
226
227
228
229
230
231
232
233 protected Session getUserSession(String principalName) {
234 return getSessionManager().getSession(principalName);
235 }
236
237
238
239
240
241
242 public void setIdGenerator(IdentifierGenerator generator) {
243 idGenerator = generator;
244 }
245
246
247
248
249
250
251 public void setInboundBinding(String binding) {
252 inboundBinding = binding;
253 }
254
255
256
257
258
259
260 public void setMessageDecoders(Map<String, SAMLMessageDecoder> decoders) {
261 messageDecoders = decoders;
262 }
263
264
265
266
267
268
269 public void setMessageEncoders(Map<String, SAMLMessageEncoder> encoders) {
270 messageEncoders = encoders;
271 }
272
273
274
275
276
277
278 public void setSupportedOutboundBindings(List<String> bindings) {
279 supportedOutboundBindings = bindings;
280 }
281
282
283 public RelyingPartyConfiguration getRelyingPartyConfiguration(String relyingPartyId) {
284 try {
285 if (getMetadataProvider().getEntityDescriptor(relyingPartyId) == null) {
286 log.warn("No metadata for relying party {}, treating party as anonymous", relyingPartyId);
287 return getRelyingPartyConfigurationManager().getAnonymousRelyingConfiguration();
288 }
289 } catch (MetadataProviderException e) {
290 log.error("Unable to look up relying party metadata", e);
291 return null;
292 }
293
294 return super.getRelyingPartyConfiguration(relyingPartyId);
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310 protected void populateRequestContext(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
311 populateRelyingPartyInformation(requestContext);
312 populateAssertingPartyInformation(requestContext);
313 populateSAMLMessageInformation(requestContext);
314 populateProfileInformation(requestContext);
315 populateUserInformation(requestContext);
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 protected void populateRelyingPartyInformation(BaseSAMLProfileRequestContext requestContext)
330 throws ProfileException {
331 MetadataProvider metadataProvider = requestContext.getMetadataProvider();
332 String relyingPartyId = requestContext.getInboundMessageIssuer();
333 requestContext.setPeerEntityId(relyingPartyId);
334
335 EntityDescriptor relyingPartyMetadata;
336 try {
337 relyingPartyMetadata = metadataProvider.getEntityDescriptor(relyingPartyId);
338 requestContext.setPeerEntityMetadata(relyingPartyMetadata);
339 } catch (MetadataProviderException e) {
340 log.error("Error looking up metadata for relying party " + relyingPartyId, e);
341 throw new ProfileException("Error looking up metadata for relying party " + relyingPartyId);
342 }
343
344 RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(relyingPartyId);
345 if (rpConfig == null) {
346 log.error("Unable to retrieve relying party configuration data for entity with ID {}", relyingPartyId);
347 throw new ProfileException("Unable to retrieve relying party configuration data for entity with ID "
348 + relyingPartyId);
349 }
350 requestContext.setRelyingPartyConfiguration(rpConfig);
351 }
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368 protected void populateAssertingPartyInformation(BaseSAMLProfileRequestContext requestContext)
369 throws ProfileException {
370 String assertingPartyId = requestContext.getRelyingPartyConfiguration().getProviderId();
371 requestContext.setLocalEntityId(assertingPartyId);
372 requestContext.setOutboundMessageIssuer(assertingPartyId);
373
374 try {
375 EntityDescriptor localEntityDescriptor = requestContext.getMetadataProvider().getEntityDescriptor(
376 assertingPartyId);
377 if (localEntityDescriptor != null) {
378 requestContext.setLocalEntityMetadata(localEntityDescriptor);
379 }
380 } catch (MetadataProviderException e) {
381 log.error("Error looking up metadata for asserting party " + assertingPartyId, e);
382 throw new ProfileException("Error looking up metadata for asserting party " + assertingPartyId);
383 }
384 }
385
386
387
388
389
390
391
392
393
394
395
396
397
398 protected abstract void populateSAMLMessageInformation(BaseSAMLProfileRequestContext requestContext)
399 throws ProfileException;
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 protected void populateProfileInformation(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
419 AbstractSAMLProfileConfiguration profileConfig = (AbstractSAMLProfileConfiguration) requestContext
420 .getRelyingPartyConfiguration().getProfileConfiguration(getProfileId());
421 if (profileConfig != null) {
422 requestContext.setProfileConfiguration(profileConfig);
423 requestContext.setOutboundMessageArtifactType(profileConfig.getOutboundArtifactType());
424 }
425
426 Endpoint endpoint = selectEndpoint(requestContext);
427 if (endpoint == null) {
428 log.error("No return endpoint available for relying party {}", requestContext.getInboundMessageIssuer());
429 throw new ProfileException("No peer endpoint available to which to send SAML response");
430 }
431 requestContext.setPeerEntityEndpoint(endpoint);
432 }
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 protected <T extends SAMLNameIdentifierEncoder> Pair<BaseAttribute, T> selectNameIDAttributeAndEncoder(
451 Class<T> nameIdEncoderType, BaseSAMLProfileRequestContext requestContext) throws ProfileException {
452
453 Collection<BaseAttribute<?>> principalAttributes;
454 if (requestContext.getAttributes() == null) {
455 principalAttributes = Collections.emptyList();
456 } else {
457 principalAttributes = new ArrayList<BaseAttribute<?>>(requestContext.getAttributes().values());
458 }
459
460 filterNameIDAttributesByProtocol(principalAttributes, nameIdEncoderType);
461
462 String requiredNameFormat = DatatypeHelper.safeTrimOrNullString(getRequiredNameIDFormat(requestContext));
463 if (requiredNameFormat != null) {
464 log.debug(
465 "Attempting to select name identifier attribute for relying party '{}' that requires format '{}'",
466 requestContext.getInboundMessageIssuer(), requiredNameFormat);
467 filterNameIDAttributesByFormats(principalAttributes, Collections.singleton(requiredNameFormat));
468 if (principalAttributes.isEmpty()) {
469 String requiredNameFormatErr = "No attribute of principal '" + requestContext.getPrincipalName()
470 + "' can be encoded in to a NameIdentifier of " + "required format '" + requiredNameFormat
471 + "' for relying party '" + requestContext.getInboundMessageIssuer() + "'";
472 log.warn(requiredNameFormatErr);
473 throw new ProfileException(requiredNameFormatErr);
474 }
475 } else {
476 filterNameIDAttributesByFormats(principalAttributes, getSupportedNameFormats(requestContext));
477 }
478
479 Pair<BaseAttribute, T> nameIdAttributeAndEncoder = selectNameIDAttributeAndEncoder(principalAttributes,
480 nameIdEncoderType, requestContext.getRelyingPartyConfiguration().getNameIdFormatPrecedence());
481 if (nameIdAttributeAndEncoder != null) {
482 log.debug("Name identifier for relying party '{}' will be built from attribute '{}'",
483 requestContext.getInboundMessageIssuer(), nameIdAttributeAndEncoder.getFirst().getId());
484 } else {
485 log.debug(
486 "No attributes for principal '{}' support encoding into a supported name identifier format for relying party '{}'",
487 requestContext.getPrincipalName(), requestContext.getInboundMessageIssuer());
488 }
489 return nameIdAttributeAndEncoder;
490 }
491
492
493
494
495
496
497
498
499
500
501
502 protected <T extends SAMLNameIdentifierEncoder> void filterNameIDAttributesByProtocol(
503 Collection<BaseAttribute<?>> attributes, Class<T> nameIdEncoderType) {
504 if(attributes.isEmpty()){
505 return;
506 }
507
508 log.debug("Filtering out potential name identifier attributes which can not be encoded by {}",
509 nameIdEncoderType.getName());
510
511 BaseAttribute<?> attribute;
512
513 Iterator<BaseAttribute<?>> attributeItr = attributes.iterator();
514 ATTRIBS: while (attributeItr.hasNext()) {
515 attribute = attributeItr.next();
516 for (AttributeEncoder encoder : attribute.getEncoders()) {
517 if (encoder == null) {
518 continue;
519 }
520
521 if (nameIdEncoderType.isInstance(encoder)) {
522 log.debug("Retaining attribute {} which may be encoded to via {}", attribute.getId(),
523 nameIdEncoderType.getName());
524 continue ATTRIBS;
525 }
526 }
527 log.debug("Removing attribute {}, it can not be encoded via {}", attribute.getId(),
528 nameIdEncoderType.getName());
529 attributeItr.remove();
530 }
531 }
532
533
534
535
536
537
538
539
540
541 protected void filterNameIDAttributesByFormats(Collection<BaseAttribute<?>> attributes,
542 Collection<String> acceptableFormats) {
543 if (attributes.isEmpty() || acceptableFormats == null || acceptableFormats.isEmpty()) {
544 return;
545 }
546
547 log.debug(
548 "Filtering out potential name identifier attributes which do not support one of the following formats: {}",
549 acceptableFormats);
550
551 BaseAttribute<?> attribute;
552 SAMLNameIdentifierEncoder nameIdEncoder;
553
554 Iterator<BaseAttribute<?>> attributeItr = attributes.iterator();
555 ATTRIBS: while (attributeItr.hasNext()) {
556 attribute = attributeItr.next();
557 for (AttributeEncoder encoder : attribute.getEncoders()) {
558 if (encoder == null) {
559 continue;
560 }
561
562 if (encoder instanceof SAMLNameIdentifierEncoder) {
563 nameIdEncoder = (SAMLNameIdentifierEncoder) encoder;
564 if (acceptableFormats.contains(nameIdEncoder.getNameFormat())) {
565
566 log.debug("Retaining attribute {} which may be encoded as a name identifier of format {}",
567 attribute.getId(), nameIdEncoder.getNameFormat());
568 continue ATTRIBS;
569 }
570 }
571 }
572 log.debug("Removing attribute {}, it can not be encoded in to a name identifier of an acceptable format",
573 attribute.getId());
574 attributeItr.remove();
575 }
576 }
577
578
579
580
581
582
583
584
585
586
587
588 protected String getRequiredNameIDFormat(BaseSAMLProfileRequestContext requestContext) {
589 return null;
590 }
591
592
593
594
595
596
597
598
599
600
601
602 protected List<String> getSupportedNameFormats(BaseSAMLProfileRequestContext requestContext)
603 throws ProfileException {
604 ArrayList<String> nameFormats = new ArrayList<String>();
605
606 RoleDescriptor relyingPartyRole = requestContext.getPeerEntityRoleMetadata();
607 if (relyingPartyRole != null) {
608 List<String> relyingPartySupportedFormats = getEntitySupportedFormats(relyingPartyRole);
609 if (relyingPartySupportedFormats != null && !relyingPartySupportedFormats.isEmpty()) {
610 nameFormats.addAll(relyingPartySupportedFormats);
611 }
612 }
613
614
615 if (nameFormats.contains(NameIdentifier.UNSPECIFIED)) {
616 nameFormats.clear();
617 }
618
619 return nameFormats;
620 }
621
622
623
624
625
626
627
628
629 protected List<String> getEntitySupportedFormats(RoleDescriptor role) {
630 List<NameIDFormat> nameIDFormats = null;
631
632 if (role instanceof SSODescriptor) {
633 nameIDFormats = ((SSODescriptor) role).getNameIDFormats();
634 } else if (role instanceof AuthnAuthorityDescriptor) {
635 nameIDFormats = ((AuthnAuthorityDescriptor) role).getNameIDFormats();
636 } else if (role instanceof PDPDescriptor) {
637 nameIDFormats = ((PDPDescriptor) role).getNameIDFormats();
638 } else if (role instanceof AttributeAuthorityDescriptor) {
639 nameIDFormats = ((AttributeAuthorityDescriptor) role).getNameIDFormats();
640 }
641
642 ArrayList<String> supportedFormats = new ArrayList<String>();
643 if (nameIDFormats != null) {
644 for (NameIDFormat format : nameIDFormats) {
645 supportedFormats.add(format.getFormat());
646 }
647 }
648
649 return supportedFormats;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665 protected <T extends SAMLNameIdentifierEncoder> Pair<BaseAttribute, T> selectNameIDAttributeAndEncoder(
666 Collection<BaseAttribute<?>> attributes, Class<T> nameIdEncoderType, String[] formatPrecedence) {
667 if (attributes.isEmpty()) {
668 return null;
669 }
670
671 log.debug("Selecting attribute to be encoded as a name identifier by encoder of type {}",
672 nameIdEncoderType.getName());
673
674 T nameIdEncoder;
675
676 if (formatPrecedence != null) {
677 log.debug("Attempting to select name identifier with highest precedence");
678 for (String format : formatPrecedence) {
679 for (BaseAttribute<?> attribute : attributes) {
680 for (AttributeEncoder encoder : attribute.getEncoders()) {
681 if (encoder == null) {
682 continue;
683 }
684
685 if (nameIdEncoderType.isInstance(encoder)) {
686 nameIdEncoder = (T) encoder;
687 if (DatatypeHelper.safeEquals(format, nameIdEncoder.getNameFormat())) {
688 return new Pair<BaseAttribute, T>(attribute, nameIdEncoder);
689 }
690 }
691 }
692 }
693 log.debug("No attribute can be encoded as a name identifier with format {}", format);
694 }
695 log.debug("No attribute can be encoded in to a name identifer with a format given in the precdence list.");
696 }
697
698 log.debug("Selecting the first attribute that can be encoded in to a name identifier");
699 BaseAttribute<?> attribute = attributes.iterator().next();
700 for (AttributeEncoder encoder : attribute.getEncoders()) {
701 if (encoder == null) {
702 continue;
703 }
704
705 if (nameIdEncoderType.isInstance(encoder)) {
706 nameIdEncoder = (T) encoder;
707 return new Pair<BaseAttribute, T>(attribute, nameIdEncoder);
708 }
709 }
710
711 return null;
712 }
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729 protected abstract void populateUserInformation(BaseSAMLProfileRequestContext requestContext)
730 throws ProfileException;
731
732
733
734
735
736
737
738
739
740
741 protected abstract Endpoint selectEndpoint(BaseSAMLProfileRequestContext requestContext) throws ProfileException;
742
743
744
745
746
747
748
749
750 protected void encodeResponse(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
751 try {
752 SAMLMessageEncoder encoder = getOutboundMessageEncoder(requestContext);
753
754 AbstractSAMLProfileConfiguration profileConfig = (AbstractSAMLProfileConfiguration) requestContext
755 .getProfileConfiguration();
756 if (profileConfig != null) {
757 if (isSignResponse(requestContext)) {
758 Credential signingCredential = profileConfig.getSigningCredential();
759 if (signingCredential == null) {
760 signingCredential = requestContext.getRelyingPartyConfiguration().getDefaultSigningCredential();
761 }
762
763 if (signingCredential == null) {
764 throw new ProfileException(
765 "Signing of responses is required but no signing credential is available");
766 }
767
768 if (signingCredential.getPrivateKey() == null) {
769 throw new ProfileException(
770 "Signing of response is required but signing credential does not have a private key");
771 }
772
773 requestContext.setOutboundSAMLMessageSigningCredential(signingCredential);
774 }
775 }
776
777 log.debug("Encoding response to SAML request {} from relying party {}",
778 requestContext.getInboundSAMLMessageId(), requestContext.getInboundMessageIssuer());
779
780 requestContext.setMessageEncoder(encoder);
781 encoder.encode(requestContext);
782 } catch (MessageEncodingException e) {
783 throw new ProfileException("Unable to encode response to relying party: "
784 + requestContext.getInboundMessageIssuer(), e);
785 }
786 }
787
788
789
790
791
792
793
794
795 protected boolean isSignResponse(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
796
797 SAMLMessageEncoder encoder = getOutboundMessageEncoder(requestContext);
798
799 AbstractSAMLProfileConfiguration profileConfig = (AbstractSAMLProfileConfiguration) requestContext
800 .getProfileConfiguration();
801
802 if (profileConfig != null) {
803 try {
804 return profileConfig.getSignResponses() == CryptoOperationRequirementLevel.always
805 || (profileConfig.getSignResponses() == CryptoOperationRequirementLevel.conditional && !encoder
806 .providesMessageIntegrity(requestContext));
807 } catch (MessageEncodingException e) {
808 log.error("Unable to determine if outbound encoding '{}' provides message integrity protection",
809 encoder.getBindingURI());
810 throw new ProfileException("Unable to determine if outbound response should be signed");
811 }
812 } else {
813 return false;
814 }
815
816 }
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837 protected SAMLMessageEncoder getOutboundMessageEncoder(BaseSAMLProfileRequestContext requestContext)
838 throws ProfileException {
839 SAMLMessageEncoder encoder = null;
840
841 Endpoint endpoint = requestContext.getPeerEntityEndpoint();
842 if (endpoint == null) {
843 log.warn("No peer endpoint available for peer. Unable to send response.");
844 throw new ProfileException("No peer endpoint available for peer. Unable to send response.");
845 }
846
847 if (endpoint != null) {
848 encoder = getMessageEncoders().get(endpoint.getBinding());
849 if (encoder == null) {
850 log.error("No outbound message encoder configured for binding: {}", requestContext
851 .getPeerEntityEndpoint().getBinding());
852 throw new ProfileException("No outbound message encoder configured for binding: "
853 + requestContext.getPeerEntityEndpoint().getBinding());
854 }
855 }
856 return encoder;
857 }
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875 protected SAMLMessageDecoder getInboundMessageDecoder(BaseSAMLProfileRequestContext requestContext)
876 throws ProfileException {
877 SAMLMessageDecoder decoder = null;
878
879 decoder = getMessageDecoders().get(getInboundBinding());
880 if (decoder == null) {
881 log.error("No inbound message decoder configured for binding: {}", getInboundBinding());
882 throw new ProfileException("No inbound message decoder configured for binding: " + getInboundBinding());
883 }
884 return decoder;
885 }
886
887
888
889
890
891
892 protected void writeAuditLogEntry(BaseSAMLProfileRequestContext context) {
893 AuditLogEntry auditLogEntry = new AuditLogEntry();
894 auditLogEntry.setMessageProfile(getProfileId());
895 auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
896 auditLogEntry.setPrincipalName(context.getPrincipalName());
897 auditLogEntry.setAssertingPartyId(context.getLocalEntityId());
898 auditLogEntry.setRelyingPartyId(context.getInboundMessageIssuer());
899 auditLogEntry.setRequestBinding(context.getMessageDecoder().getBindingURI());
900 auditLogEntry.setRequestId(context.getInboundSAMLMessageId());
901 auditLogEntry.setResponseBinding(context.getMessageEncoder().getBindingURI());
902 auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
903 if (context.getReleasedAttributes() != null) {
904 auditLogEntry.getReleasedAttributes().addAll(context.getReleasedAttributes());
905 }
906
907 getAduitLog().info(auditLogEntry.toString());
908 }
909 }