1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.idp.profile.saml1;
18
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.xml.namespace.QName;
24
25 import org.joda.time.DateTime;
26 import org.opensaml.Configuration;
27 import org.opensaml.common.SAMLObject;
28 import org.opensaml.common.SAMLObjectBuilder;
29 import org.opensaml.common.SAMLVersion;
30 import org.opensaml.common.binding.encoding.SAMLMessageEncoder;
31 import org.opensaml.saml1.core.Assertion;
32 import org.opensaml.saml1.core.AttributeQuery;
33 import org.opensaml.saml1.core.AttributeStatement;
34 import org.opensaml.saml1.core.Audience;
35 import org.opensaml.saml1.core.AudienceRestrictionCondition;
36 import org.opensaml.saml1.core.Conditions;
37 import org.opensaml.saml1.core.ConfirmationMethod;
38 import org.opensaml.saml1.core.NameIdentifier;
39 import org.opensaml.saml1.core.RequestAbstractType;
40 import org.opensaml.saml1.core.Response;
41 import org.opensaml.saml1.core.ResponseAbstractType;
42 import org.opensaml.saml1.core.Statement;
43 import org.opensaml.saml1.core.Status;
44 import org.opensaml.saml1.core.StatusCode;
45 import org.opensaml.saml1.core.StatusMessage;
46 import org.opensaml.saml1.core.Subject;
47 import org.opensaml.saml1.core.SubjectConfirmation;
48 import org.opensaml.saml2.metadata.SPSSODescriptor;
49 import org.opensaml.ws.message.encoder.MessageEncodingException;
50 import org.opensaml.xml.XMLObjectBuilder;
51 import org.opensaml.xml.io.Marshaller;
52 import org.opensaml.xml.io.MarshallingException;
53 import org.opensaml.xml.security.SecurityException;
54 import org.opensaml.xml.security.SecurityHelper;
55 import org.opensaml.xml.security.credential.Credential;
56 import org.opensaml.xml.signature.Signature;
57 import org.opensaml.xml.signature.SignatureException;
58 import org.opensaml.xml.signature.Signer;
59 import org.opensaml.xml.util.Pair;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63 import edu.internet2.middleware.shibboleth.common.attribute.AttributeRequestException;
64 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
65 import edu.internet2.middleware.shibboleth.common.attribute.encoding.AttributeEncodingException;
66 import edu.internet2.middleware.shibboleth.common.attribute.encoding.SAML1NameIdentifierEncoder;
67 import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML1AttributeAuthority;
68 import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
69 import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
70 import edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext;
71 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.CryptoOperationRequirementLevel;
72 import edu.internet2.middleware.shibboleth.common.relyingparty.provider.saml1.AbstractSAML1ProfileConfiguration;
73 import edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler;
74 import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
75 import edu.internet2.middleware.shibboleth.idp.session.Session;
76
77
78 public abstract class AbstractSAML1ProfileHandler extends AbstractSAMLProfileHandler {
79
80
81 public static final SAMLVersion SAML_VERSION = SAMLVersion.VERSION_11;
82
83
84 private static Logger log = LoggerFactory.getLogger(AbstractSAML1ProfileHandler.class);
85
86
87 private SAMLObjectBuilder<Response> responseBuilder;
88
89
90 private SAMLObjectBuilder<Assertion> assertionBuilder;
91
92
93 private SAMLObjectBuilder<Conditions> conditionsBuilder;
94
95
96 private SAMLObjectBuilder<AudienceRestrictionCondition> audienceRestrictionConditionBuilder;
97
98
99 private SAMLObjectBuilder<Audience> audienceBuilder;
100
101
102 private SAMLObjectBuilder<SubjectConfirmation> subjectConfirmationBuilder;
103
104
105 private SAMLObjectBuilder<ConfirmationMethod> confirmationMethodBuilder;
106
107
108 private SAMLObjectBuilder<Subject> subjectBuilder;
109
110
111 private SAMLObjectBuilder<Status> statusBuilder;
112
113
114 private SAMLObjectBuilder<StatusCode> statusCodeBuilder;
115
116
117 private SAMLObjectBuilder<StatusMessage> statusMessageBuilder;
118
119
120 private XMLObjectBuilder<Signature> signatureBuilder;
121
122
123
124
125 @SuppressWarnings("unchecked")
126 public AbstractSAML1ProfileHandler() {
127 super();
128 responseBuilder = (SAMLObjectBuilder<Response>) getBuilderFactory().getBuilder(Response.DEFAULT_ELEMENT_NAME);
129 assertionBuilder = (SAMLObjectBuilder<Assertion>) getBuilderFactory()
130 .getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
131 conditionsBuilder = (SAMLObjectBuilder<Conditions>) getBuilderFactory().getBuilder(
132 Conditions.DEFAULT_ELEMENT_NAME);
133 audienceRestrictionConditionBuilder = (SAMLObjectBuilder<AudienceRestrictionCondition>) getBuilderFactory()
134 .getBuilder(AudienceRestrictionCondition.DEFAULT_ELEMENT_NAME);
135 audienceBuilder = (SAMLObjectBuilder<Audience>) getBuilderFactory().getBuilder(Audience.DEFAULT_ELEMENT_NAME);
136 subjectConfirmationBuilder = (SAMLObjectBuilder<SubjectConfirmation>) getBuilderFactory().getBuilder(
137 SubjectConfirmation.DEFAULT_ELEMENT_NAME);
138 confirmationMethodBuilder = (SAMLObjectBuilder<ConfirmationMethod>) getBuilderFactory().getBuilder(
139 ConfirmationMethod.DEFAULT_ELEMENT_NAME);
140 subjectBuilder = (SAMLObjectBuilder<Subject>) getBuilderFactory().getBuilder(Subject.DEFAULT_ELEMENT_NAME);
141 statusBuilder = (SAMLObjectBuilder<Status>) getBuilderFactory().getBuilder(Status.DEFAULT_ELEMENT_NAME);
142 statusCodeBuilder = (SAMLObjectBuilder<StatusCode>) getBuilderFactory().getBuilder(
143 StatusCode.DEFAULT_ELEMENT_NAME);
144 statusMessageBuilder = (SAMLObjectBuilder<StatusMessage>) getBuilderFactory().getBuilder(
145 StatusMessage.DEFAULT_ELEMENT_NAME);
146 signatureBuilder = (XMLObjectBuilder<Signature>) getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME);
147 }
148
149
150 protected void populateRequestContext(BaseSAMLProfileRequestContext requestContext) throws ProfileException {
151 BaseSAML1ProfileRequestContext saml1Request = (BaseSAML1ProfileRequestContext) requestContext;
152 try {
153 super.populateRequestContext(requestContext);
154 } catch (ProfileException e) {
155 if (saml1Request.getFailureStatus() == null) {
156 saml1Request.setFailureStatus(buildStatus(StatusCode.REQUESTER, null, e.getMessage()));
157 }
158 throw e;
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173 protected void populateUserInformation(BaseSAMLProfileRequestContext requestContext) {
174 Session userSession = getUserSession(requestContext.getInboundMessageTransport());
175 if (userSession == null) {
176 NameIdentifier subject = (NameIdentifier) requestContext.getSubjectNameIdentifier();
177 if (subject != null && subject.getNameIdentifier() != null) {
178 userSession = getUserSession(subject.getNameIdentifier());
179 }
180 }
181
182 if (userSession != null) {
183 requestContext.setUserSession(userSession);
184 requestContext.setPrincipalName(userSession.getPrincipalName());
185 ServiceInformation serviceInfo = userSession.getServicesInformation().get(
186 requestContext.getInboundMessageIssuer());
187 if (serviceInfo != null) {
188 requestContext.setPrincipalAuthenticationMethod(serviceInfo.getAuthenticationMethod()
189 .getAuthenticationMethod());
190 }
191 }
192 }
193
194
195
196
197
198
199
200
201 protected void checkSamlVersion(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext) throws ProfileException {
202 SAMLObject samlObject = requestContext.getInboundSAMLMessage();
203
204 if (samlObject instanceof RequestAbstractType) {
205 RequestAbstractType request = (RequestAbstractType) samlObject;
206 if (request.getMajorVersion() < 1) {
207 requestContext.setFailureStatus(buildStatus(StatusCode.REQUESTER, StatusCode.REQUEST_VERSION_TOO_LOW,
208 null));
209 throw new ProfileException("SAML request major version too low");
210 } else if (request.getMajorVersion() > 1) {
211 requestContext.setFailureStatus(buildStatus(StatusCode.REQUESTER, StatusCode.REQUEST_VERSION_TOO_HIGH,
212 null));
213 throw new ProfileException("SAML request major version too low");
214 }
215 }
216 }
217
218
219
220
221
222
223
224
225
226
227
228 protected Response buildResponse(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, List<Statement> statements)
229 throws ProfileException {
230
231 DateTime issueInstant = new DateTime();
232
233
234 Response samlResponse = responseBuilder.buildObject();
235 samlResponse.setIssueInstant(issueInstant);
236 populateStatusResponse(requestContext, samlResponse);
237
238
239 Assertion assertion = null;
240 if (statements != null && !statements.isEmpty()) {
241 assertion = buildAssertion(requestContext, issueInstant);
242 assertion.getStatements().addAll(statements);
243 samlResponse.getAssertions().add(assertion);
244 signAssertion(requestContext, assertion);
245 }
246
247 Status status = buildStatus(StatusCode.SUCCESS, null, null);
248 samlResponse.setStatus(status);
249
250 return samlResponse;
251 }
252
253
254
255
256
257
258
259
260
261 protected Assertion buildAssertion(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, DateTime issueInstant) {
262 Assertion assertion = assertionBuilder.buildObject();
263 assertion.setID(getIdGenerator().generateIdentifier());
264 assertion.setIssueInstant(issueInstant);
265 assertion.setVersion(SAMLVersion.VERSION_11);
266 assertion.setIssuer(requestContext.getLocalEntityId());
267
268 Conditions conditions = buildConditions(requestContext, issueInstant);
269 assertion.setConditions(conditions);
270
271 return assertion;
272 }
273
274
275
276
277
278
279
280
281
282
283 protected Conditions buildConditions(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, DateTime issueInstant) {
284 AbstractSAML1ProfileConfiguration profileConfig = requestContext.getProfileConfiguration();
285
286 Conditions conditions = conditionsBuilder.buildObject();
287 conditions.setNotBefore(issueInstant);
288 conditions.setNotOnOrAfter(issueInstant.plus(profileConfig.getAssertionLifetime()));
289
290 Collection<String> audiences;
291
292 AudienceRestrictionCondition audienceRestriction = audienceRestrictionConditionBuilder.buildObject();
293 conditions.getAudienceRestrictionConditions().add(audienceRestriction);
294
295 Audience audience = audienceBuilder.buildObject();
296 audience.setUri(requestContext.getInboundMessageIssuer());
297 audienceRestriction.getAudiences().add(audience);
298
299
300 audiences = profileConfig.getAssertionAudiences();
301 if (audiences != null && audiences.size() > 0) {
302 for (String audienceUri : audiences) {
303 audience = audienceBuilder.buildObject();
304 audience.setUri(audienceUri);
305 audienceRestriction.getAudiences().add(audience);
306 }
307 }
308
309 return conditions;
310 }
311
312
313
314
315
316
317
318
319
320
321
322
323 protected Subject buildSubject(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, String confirmationMethod)
324 throws ProfileException {
325
326 ConfirmationMethod method = confirmationMethodBuilder.buildObject();
327 method.setConfirmationMethod(confirmationMethod);
328
329 SubjectConfirmation subjectConfirmation = subjectConfirmationBuilder.buildObject();
330 subjectConfirmation.getConfirmationMethods().add(method);
331
332 Subject subject = subjectBuilder.buildObject();
333 subject.setSubjectConfirmation(subjectConfirmation);
334
335 NameIdentifier nameID = buildNameId(requestContext);
336 if (nameID != null) {
337 subject.setNameIdentifier(nameID);
338 requestContext.setSubjectNameIdentifier(nameID);
339 }
340
341 return subject;
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 protected NameIdentifier buildNameId(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext)
359 throws ProfileException {
360 Pair<BaseAttribute, SAML1NameIdentifierEncoder> nameIdAttributeAndEncoder = null;
361 try {
362 nameIdAttributeAndEncoder = selectNameIDAttributeAndEncoder(SAML1NameIdentifierEncoder.class,
363 requestContext);
364 } catch (ProfileException e) {
365 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null,
366 "Required NameIdentifier format not supported"));
367 throw e;
368 }
369
370 if (nameIdAttributeAndEncoder == null) {
371 return null;
372 }
373
374 BaseAttribute<?> nameIdAttribute = nameIdAttributeAndEncoder.getFirst();
375 requestContext.setNameIdentifierAttribute(nameIdAttribute);
376 SAML1NameIdentifierEncoder nameIdEncoder = nameIdAttributeAndEncoder.getSecond();
377
378 try {
379 log
380 .debug(
381 "Using attribute '{}' supporting name format '{}' to create the NameIdentifier for relying party '{}'",
382 new Object[] { nameIdAttribute.getId(), nameIdEncoder.getNameFormat(),
383 requestContext.getInboundMessageIssuer(), });
384 NameIdentifier nameId = nameIdEncoder.encode(nameIdAttribute);
385 if (nameId.getNameQualifier() == null) {
386 nameId.setNameQualifier(requestContext.getRelyingPartyConfiguration().getProviderId());
387 }
388 return nameId;
389 } catch (AttributeEncodingException e) {
390 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Unable to encode NameIdentifier"));
391 String msg = "Unable to encode NameIdentifier for relying party "
392 + requestContext.getInboundMessageIssuer();
393 log.error(msg, e);
394 throw new ProfileException(msg, e);
395 }
396 }
397
398
399
400
401
402
403
404
405 protected Response buildErrorResponse(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext) {
406 Response samlResponse = responseBuilder.buildObject();
407 samlResponse.setIssueInstant(new DateTime());
408 populateStatusResponse(requestContext, samlResponse);
409
410 samlResponse.setStatus(requestContext.getFailureStatus());
411
412 return samlResponse;
413 }
414
415
416
417
418
419
420
421 protected void populateStatusResponse(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext,
422 ResponseAbstractType response) {
423 response.setID(getIdGenerator().generateIdentifier());
424
425 SAMLObject samlMessage = requestContext.getInboundSAMLMessage();
426 if (samlMessage != null && samlMessage instanceof RequestAbstractType) {
427 response.setInResponseTo(((RequestAbstractType) samlMessage).getID());
428 }
429
430 response.setVersion(SAMLVersion.VERSION_11);
431 }
432
433
434
435
436
437
438
439
440
441
442 protected Status buildStatus(QName topLevelCode, QName secondLevelCode, String failureMessage) {
443 Status status = statusBuilder.buildObject();
444
445 StatusCode statusCode = statusCodeBuilder.buildObject();
446 statusCode.setValue(topLevelCode);
447 status.setStatusCode(statusCode);
448
449 if (secondLevelCode != null) {
450 StatusCode secondLevelStatusCode = statusCodeBuilder.buildObject();
451 secondLevelStatusCode.setValue(secondLevelCode);
452 statusCode.setStatusCode(secondLevelStatusCode);
453 }
454
455 if (failureMessage != null) {
456 StatusMessage msg = statusMessageBuilder.buildObject();
457 msg.setMessage(failureMessage);
458 status.setStatusMessage(msg);
459 }
460
461 return status;
462 }
463
464
465
466
467
468
469
470
471 protected void resolveAttributes(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext) throws ProfileException {
472 AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
473 SAML1AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
474
475 try {
476 log.debug("Resolving attributes for principal '{}' for SAML request from relying party '{}'",
477 requestContext.getPrincipalName(), requestContext.getInboundMessageIssuer());
478 Map<String, BaseAttribute> principalAttributes = attributeAuthority.getAttributes(requestContext);
479
480 requestContext.setAttributes(principalAttributes);
481 } catch (AttributeRequestException e) {
482 log
483 .warn(
484 "Error resolving attributes for principal '{}'. No name identifier or attribute statement will be included in response",
485 requestContext.getPrincipalName());
486 }
487 }
488
489
490
491
492
493
494
495
496
497
498
499 protected AttributeStatement buildAttributeStatement(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext,
500 String subjectConfMethod) throws ProfileException {
501
502 if (requestContext.getAttributes() == null) {
503 return null;
504 }
505
506 log.debug(
507 "Creating attribute statement about principal '{}'in response to SAML request from relying party '{}'",
508 requestContext.getPrincipalName(), requestContext.getInboundMessageIssuer());
509 AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
510 SAML1AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
511
512 try {
513 AttributeStatement statment;
514 if (requestContext.getInboundSAMLMessage() instanceof AttributeQuery) {
515 statment = attributeAuthority.buildAttributeStatement((AttributeQuery) requestContext
516 .getInboundSAMLMessage(), requestContext.getAttributes().values());
517 } else {
518 statment = attributeAuthority.buildAttributeStatement(null, requestContext.getAttributes().values());
519 }
520
521 if (statment != null) {
522 Subject statementSubject = buildSubject(requestContext, subjectConfMethod);
523 statment.setSubject(statementSubject);
524 }
525
526 return statment;
527 } catch (AttributeRequestException e) {
528 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, null, "Error resolving attributes"));
529 String msg = "Error encoding attributes for principal " + requestContext.getPrincipalName();
530 log.error(msg, e);
531 throw new ProfileException(msg, e);
532 }
533 }
534
535
536
537
538
539
540
541
542 protected void resolvePrincipal(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext) throws ProfileException {
543 AbstractSAML1ProfileConfiguration profileConfiguration = requestContext.getProfileConfiguration();
544 SAML1AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
545
546 log.debug("Resolving principal name for subject of SAML request from relying party '{}'", requestContext
547 .getInboundMessageIssuer());
548
549 try {
550 String principal = attributeAuthority.getPrincipal(requestContext);
551 requestContext.setPrincipalName(principal);
552 } catch (AttributeRequestException e) {
553 requestContext.setFailureStatus(buildStatus(StatusCode.RESPONDER, StatusCode.REQUEST_DENIED,
554 "Error resolving principal"));
555 String msg = "Error resolving principal name for SAML request from relying party '"
556 + requestContext.getInboundMessageIssuer() + "'. Cause: " + e.getMessage();
557 log.warn(msg);
558 throw new ProfileException(msg, e);
559 }
560 }
561
562
563
564
565
566
567
568
569
570
571
572 protected void signAssertion(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext, Assertion assertion)
573 throws ProfileException {
574 log.debug("Determining if SAML assertion to relying party '{}' should be signed", requestContext
575 .getInboundMessageIssuer());
576
577 boolean signAssertion = isSignAssertion(requestContext);
578
579 if (!signAssertion) {
580 return;
581 }
582
583 AbstractSAML1ProfileConfiguration profileConfig = requestContext.getProfileConfiguration();
584
585 log.debug("Determining credential to use to sign assertion to relying party '{}'", requestContext
586 .getInboundMessageIssuer());
587 Credential signatureCredential = profileConfig.getSigningCredential();
588 if (signatureCredential == null) {
589 signatureCredential = requestContext.getRelyingPartyConfiguration().getDefaultSigningCredential();
590 }
591
592 if (signatureCredential == null) {
593 String msg = "No signing credential is specified for relying party configuration "
594 + requestContext.getRelyingPartyConfiguration().getProviderId();
595 log.warn(msg);
596 throw new ProfileException(msg);
597 }
598
599 log.debug("Signing assertion to relying party '{}'", requestContext.getInboundMessageIssuer());
600 Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
601
602 signature.setSigningCredential(signatureCredential);
603 try {
604
605
606 SecurityHelper.prepareSignatureParams(signature, signatureCredential, null, null);
607 } catch (SecurityException e) {
608 String msg = "Error preparing signature for signing";
609 log.error(msg);
610 throw new ProfileException(msg, e);
611 }
612
613 assertion.setSignature(signature);
614
615 Marshaller assertionMarshaller = Configuration.getMarshallerFactory().getMarshaller(assertion);
616 try {
617 assertionMarshaller.marshall(assertion);
618 Signer.signObject(signature);
619 } catch (MarshallingException e) {
620 String errMsg = "Unable to marshall assertion for signing";
621 log.error(errMsg, e);
622 throw new ProfileException(errMsg, e);
623 } catch (SignatureException e) {
624 String msg = "Unable to sign assertion";
625 log.error(msg, e);
626 throw new ProfileException(msg, e);
627 }
628 }
629
630
631
632
633
634
635
636
637 protected boolean isSignAssertion(BaseSAML1ProfileRequestContext<?, ?, ?> requestContext) throws ProfileException {
638
639 SAMLMessageEncoder encoder = getOutboundMessageEncoder(requestContext);
640 AbstractSAML1ProfileConfiguration profileConfig = requestContext.getProfileConfiguration();
641
642 try {
643 boolean signAssertion = profileConfig.getSignAssertions() == CryptoOperationRequirementLevel.always
644 || (profileConfig.getSignAssertions() == CryptoOperationRequirementLevel.conditional && !encoder
645 .providesMessageIntegrity(requestContext));
646
647 log.debug("IdP relying party configuration '{}' indicates to sign assertions: {}", requestContext
648 .getRelyingPartyConfiguration().getRelyingPartyId(), signAssertion);
649
650 if (!signAssertion && requestContext.getPeerEntityRoleMetadata() instanceof SPSSODescriptor) {
651 SPSSODescriptor ssoDescriptor = (SPSSODescriptor) requestContext.getPeerEntityRoleMetadata();
652 if (ssoDescriptor.getWantAssertionsSigned() != null) {
653 signAssertion = ssoDescriptor.getWantAssertionsSigned().booleanValue();
654 log.debug("Entity metadata for relying party '{} 'indicates to sign assertions: {}", requestContext
655 .getInboundMessageIssuer(), signAssertion);
656 }
657 }
658
659 return signAssertion;
660 } catch (MessageEncodingException e) {
661 log.error("Unable to determine if outbound encoding '{}' provides message integrity protection", encoder
662 .getBindingURI());
663 throw new ProfileException("Unable to determine if outbound assertion should be signed");
664 }
665 }
666
667
668
669
670
671
672 protected void writeAuditLogEntry(BaseSAMLProfileRequestContext context) {
673 SAML1AuditLogEntry auditLogEntry = new SAML1AuditLogEntry();
674 auditLogEntry.setSAMLResponse((Response) context.getOutboundSAMLMessage());
675 auditLogEntry.setMessageProfile(getProfileId());
676 auditLogEntry.setPrincipalAuthenticationMethod(context.getPrincipalAuthenticationMethod());
677 auditLogEntry.setPrincipalName(context.getPrincipalName());
678 auditLogEntry.setAssertingPartyId(context.getLocalEntityId());
679 auditLogEntry.setRelyingPartyId(context.getInboundMessageIssuer());
680 auditLogEntry.setRequestBinding(context.getMessageDecoder().getBindingURI());
681 auditLogEntry.setRequestId(context.getInboundSAMLMessageId());
682 auditLogEntry.setResponseBinding(context.getMessageEncoder().getBindingURI());
683 auditLogEntry.setResponseId(context.getOutboundSAMLMessageId());
684 if (context.getReleasedAttributes() != null) {
685 auditLogEntry.getReleasedAttributes().addAll(context.getReleasedAttributes());
686 }
687
688 if (context.getNameIdentifierAttribute() != null) {
689 Object idValue = context.getNameIdentifierAttribute().getValues().iterator().next();
690 if(idValue != null){
691 auditLogEntry.setNameIdValue(idValue.toString());
692 }
693 }
694
695 getAduitLog().info(auditLogEntry.toString());
696 }
697
698
699 protected class SAML1AuditLogEntry extends AuditLogEntry {
700
701
702 private Response samlResponse;
703
704
705
706
707
708
709 public Response getSAMLResponse() {
710 return samlResponse;
711 }
712
713
714
715
716
717
718 public void setSAMLResponse(Response response) {
719 samlResponse = response;
720 }
721
722
723 public String toString() {
724 StringBuilder entryString = new StringBuilder(super.toString());
725
726 StringBuilder assertionIds = new StringBuilder();
727 List<Assertion> assertions = samlResponse.getAssertions();
728 if (assertions != null && !assertions.isEmpty()) {
729 for (Assertion assertion : assertions) {
730 assertionIds.append(assertion.getID());
731 assertionIds.append(",");
732 }
733 }
734
735 if (getNameIdValue() != null) {
736 entryString.append(getNameIdValue());
737 }
738 entryString.append("|");
739
740 entryString.append(assertionIds.toString());
741 entryString.append("|");
742
743 return entryString.toString();
744 }
745 }
746 }