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