package org.pac4j.saml.context; import org.opensaml.messaging.context.MessageContext; import org.opensaml.profile.context.ProfileRequestContext; import org.opensaml.saml.common.SAMLObject; import org.opensaml.saml.common.messaging.context.SAMLBindingContext; import org.opensaml.saml.common.messaging.context.SAMLEndpointContext; import org.opensaml.saml.common.messaging.context.SAMLMetadataContext; import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext; import org.opensaml.saml.common.messaging.context.SAMLProtocolContext; import org.opensaml.saml.common.messaging.context.SAMLSelfEntityContext; import org.opensaml.saml.common.messaging.context.SAMLSubjectNameIdentifierContext; import org.opensaml.saml.saml2.core.Assertion; import org.opensaml.saml.saml2.core.BaseID; import org.opensaml.saml.saml2.core.SubjectConfirmation; import org.opensaml.saml.saml2.metadata.AssertionConsumerService; import org.opensaml.saml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml.saml2.metadata.SingleLogoutService; import org.opensaml.saml.saml2.metadata.SingleSignOnService; import org.opensaml.xmlsec.context.SecurityParametersContext; import org.pac4j.core.context.WebContext; import org.pac4j.saml.exceptions.SAMLException; import org.pac4j.saml.storage.SAMLMessageStorage; import org.pac4j.saml.transport.Pac4jSAMLResponse; import java.util.ArrayList; import java.util.List; /** * Allow to store additional information for SAML processing. * * @author Michael Remond * @version 1.5.0 */ @SuppressWarnings("rawtypes") public class SAML2MessageContext extends MessageContext<SAMLObject> { private WebContext webContext; /* valid subject assertion */ private Assertion subjectAssertion; /** BaseID retrieved either from the Subject or from a SubjectConfirmation */ private BaseID baseID; /** SubjectConfirmations used during assertion evaluation. */ private List<SubjectConfirmation> subjectConfirmations = new ArrayList<SubjectConfirmation>(); private SAMLMessageStorage samlMessageStorage; public SAML2MessageContext() { super(); } public SAML2MessageContext(final MessageContext<SAMLObject> ctx) { this(); super.setParent(ctx); } public WebContext getWebContext() { return webContext; } public void setWebContext(final WebContext webContext) { this.webContext = webContext; } public final Assertion getSubjectAssertion() { return this.subjectAssertion; } public final SPSSODescriptor getSPSSODescriptor() { final SAMLMetadataContext selfContext = getSAMLSelfMetadataContext(); final SPSSODescriptor spDescriptor = (SPSSODescriptor) selfContext.getRoleDescriptor(); return spDescriptor; } public final IDPSSODescriptor getIDPSSODescriptor() { final SAMLMetadataContext peerContext = getSAMLPeerMetadataContext(); final IDPSSODescriptor idpssoDescriptor = (IDPSSODescriptor) peerContext.getRoleDescriptor(); return idpssoDescriptor; } public final SingleLogoutService getIDPSingleLogoutService(final String binding) { final List<SingleLogoutService> services = getIDPSSODescriptor().getSingleLogoutServices(); for (final SingleLogoutService service : services) { if(service.getBinding().equals(binding)) { return service; } } throw new SAMLException("Identity provider has no single logout service available for the selected profile" + getIDPSSODescriptor()); } public final SingleSignOnService getIDPSingleSignOnService(final String binding) { final List<SingleSignOnService> services = getIDPSSODescriptor().getSingleSignOnServices(); for (final SingleSignOnService service : services) { if (service.getBinding().equals(binding)) { return service; } } throw new SAMLException("Identity provider has no single sign on service available for the selected profile" + getIDPSSODescriptor()); } public final AssertionConsumerService getSPAssertionConsumerService() { return getSPAssertionConsumerService(null); } public final AssertionConsumerService getSPAssertionConsumerService(final String acsIndex) { final SPSSODescriptor spssoDescriptor = getSPSSODescriptor(); final List<AssertionConsumerService> services = spssoDescriptor.getAssertionConsumerServices(); // Get by index if (acsIndex != null) { for (final AssertionConsumerService service : services) { if (Integer.valueOf(acsIndex).equals(service.getIndex())) { return service; } } throw new SAMLException("Assertion consumer service with index " + acsIndex + " could not be found for spDescriptor " + spssoDescriptor); } // Get default if (spssoDescriptor.getDefaultAssertionConsumerService() != null) { return spssoDescriptor.getDefaultAssertionConsumerService(); } // Get first if (!services.isEmpty()) { return services.iterator().next(); } throw new SAMLException("No assertion consumer services could be found for " + spssoDescriptor); } public final ProfileRequestContext getProfileRequestContext() { return this.getSubcontext(ProfileRequestContext.class, true); } public final SAMLSelfEntityContext getSAMLSelfEntityContext() { return this.getSubcontext(SAMLSelfEntityContext.class, true); } public final SAMLMetadataContext getSAMLSelfMetadataContext() { return getSAMLSelfEntityContext().getSubcontext(SAMLMetadataContext.class, true); } public final SAMLMetadataContext getSAMLPeerMetadataContext() { return getSAMLPeerEntityContext().getSubcontext(SAMLMetadataContext.class, true); } public final SAMLPeerEntityContext getSAMLPeerEntityContext() { return this.getSubcontext(SAMLPeerEntityContext.class, true); } public final SAMLSubjectNameIdentifierContext getSAMLSubjectNameIdentifierContext() { return this.getSubcontext(SAMLSubjectNameIdentifierContext.class, true); } public final void setSubjectAssertion(final Assertion subjectAssertion) { this.subjectAssertion = subjectAssertion; } public final BaseID getBaseID() { return baseID; } public final void setBaseID(final BaseID baseID) { this.baseID = baseID; } public final List<SubjectConfirmation> getSubjectConfirmations() { return subjectConfirmations; } public final SAMLEndpointContext getSAMLPeerEndpointContext() { return getSAMLPeerEntityContext().getSubcontext(SAMLEndpointContext.class, true); } public final SAMLEndpointContext getSAMLSelfEndpointContext() { return getSAMLSelfEntityContext().getSubcontext(SAMLEndpointContext.class, true); } public final SAMLBindingContext getSAMLBindingContext() { return this.getSubcontext(SAMLBindingContext.class, true); } public final SecurityParametersContext getSecurityParametersContext() { return this.getSubcontext(SecurityParametersContext.class, true); } public final SAMLProtocolContext getSAMLSelfProtocolContext() { return this.getSAMLSelfEntityContext().getSubcontext(SAMLProtocolContext.class, true); } public final SAMLProtocolContext getSAMLProtocolContext() { return this.getSubcontext(SAMLProtocolContext.class, true); } public final Pac4jSAMLResponse getProfileRequestContextOutboundMessageTransportResponse() { return (Pac4jSAMLResponse) getProfileRequestContext().getOutboundMessageContext().getMessage(); } public final SAMLEndpointContext getSAMLEndpointContext() { return this.getSubcontext(SAMLEndpointContext.class, true); } public final SAMLMessageStorage getSAMLMessageStorage() { return this.samlMessageStorage; } public final void setSAMLMessageStorage(final SAMLMessageStorage samlMessageStorage) { this.samlMessageStorage = samlMessageStorage; } }