package mujina.sp; import mujina.api.SpConfiguration; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.velocity.app.VelocityEngine; import org.opensaml.common.SAMLException; import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.saml2.binding.decoding.HTTPPostDecoder; import org.opensaml.saml2.binding.encoding.HTTPPostEncoder; import org.opensaml.saml2.core.Assertion; import org.opensaml.saml2.core.AuthnRequest; import org.opensaml.ws.security.SecurityPolicyRule; import org.opensaml.xml.encryption.DecryptionException; import org.opensaml.xml.parse.ParserPool; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.signature.Signature; import org.opensaml.xml.validation.ValidationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.security.core.AuthenticationException; import org.springframework.security.saml.SAMLBootstrap; import org.springframework.security.saml.context.SAMLMessageContext; import org.springframework.security.saml.log.SAMLDefaultLogger; import org.springframework.security.saml.processor.HTTPArtifactBinding; import org.springframework.security.saml.processor.HTTPPAOS11Binding; import org.springframework.security.saml.processor.HTTPPostBinding; import org.springframework.security.saml.processor.HTTPRedirectDeflateBinding; import org.springframework.security.saml.processor.HTTPSOAP11Binding; import org.springframework.security.saml.processor.SAMLBinding; import org.springframework.security.saml.processor.SAMLProcessor; import org.springframework.security.saml.websso.ArtifactResolutionProfile; import org.springframework.security.saml.websso.ArtifactResolutionProfileImpl; import org.springframework.security.saml.websso.WebSSOProfile; import org.springframework.security.saml.websso.WebSSOProfileConsumer; import org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl; import org.springframework.security.saml.websso.WebSSOProfileConsumerImpl; import org.springframework.security.saml.websso.WebSSOProfileECPImpl; import org.springframework.security.saml.websso.WebSSOProfileImpl; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Typically this should all be done by default convention in the Spring SAML library, * but as Spring SAML is not build with conventions over configuration we do all the * plumbing ourselves. */ @Configuration public class SAMLConfig { @Autowired private Environment environment; @Bean public MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager() { return new MultiThreadedHttpConnectionManager(); } @Bean public HttpClient httpClient() { return new HttpClient(multiThreadedHttpConnectionManager()); } private HTTPArtifactBinding artifactBinding(ParserPool parserPool, VelocityEngine velocityEngine, ArtifactResolutionProfile artifactResolutionProfile) { return new HTTPArtifactBinding(parserPool, velocityEngine, artifactResolutionProfile); } @Bean @Autowired public HTTPSOAP11Binding soapBinding(ParserPool parserPool) { return new HTTPSOAP11Binding(parserPool); } @Bean @Autowired public HTTPPostBinding httpPostBinding(ParserPool parserPool, VelocityEngine velocityEngine, @Value("${sp.compare_endpoints}") boolean compareEndpoints) { HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm"); HTTPPostDecoder decoder = new HTTPPostDecoder(parserPool); if (!compareEndpoints) { decoder.setURIComparator((uri1, uri2) -> true); } return new HTTPPostBinding(parserPool, decoder, encoder); } @Bean @Autowired public HTTPRedirectDeflateBinding httpRedirectDeflateBinding(ParserPool parserPool) { return new HTTPRedirectDeflateBinding(parserPool); } @Bean @Autowired public HTTPSOAP11Binding httpSOAP11Binding(ParserPool parserPool) { return new HTTPSOAP11Binding(parserPool); } @Bean @Autowired public HTTPPAOS11Binding httpPAOS11Binding(ParserPool parserPool) { return new HTTPPAOS11Binding(parserPool); } @Autowired @Bean public SAMLProcessor processor(VelocityEngine velocityEngine, ParserPool parserPool, SpConfiguration spConfiguration, @Value("${sp.compare_endpoints}") boolean compareEndpoints) { ArtifactResolutionProfile artifactResolutionProfile = new ArtifactResolutionProfileImpl(httpClient()); Collection<SAMLBinding> bindings = new ArrayList<>(); bindings.add(httpRedirectDeflateBinding(parserPool)); bindings.add(httpPostBinding(parserPool, velocityEngine, compareEndpoints)); bindings.add(artifactBinding(parserPool, velocityEngine, artifactResolutionProfile)); bindings.add(httpSOAP11Binding(parserPool)); bindings.add(httpPAOS11Binding(parserPool)); return new ConfigurableSAMLProcessor(bindings, spConfiguration); } @Bean public static SAMLBootstrap sAMLBootstrap() { return new SAMLBootstrap(); } @Bean public SAMLDefaultLogger samlLogger() { return new SAMLDefaultLogger(); } @Bean public WebSSOProfileConsumer webSSOprofileConsumer() { WebSSOProfileConsumerImpl webSSOProfileConsumer = environment.acceptsProfiles("test") ? new WebSSOProfileConsumerImpl() { @Override protected void verifyAssertion(Assertion assertion, AuthnRequest request, SAMLMessageContext context) throws AuthenticationException, SAMLException, org.opensaml.xml.security.SecurityException, ValidationException, DecryptionException { //nope context.setSubjectNameIdentifier(assertion.getSubject().getNameID()); } } : new WebSSOProfileConsumerImpl(); webSSOProfileConsumer.setResponseSkew(15 * 60); return webSSOProfileConsumer; } @Bean public WebSSOProfileConsumerHoKImpl hokWebSSOprofileConsumer() { return new WebSSOProfileConsumerHoKImpl(); } @Bean @Autowired public WebSSOProfile webSSOprofile(SAMLProcessor samlProcessor) { WebSSOProfileImpl webSSOProfile = new WebSSOProfileImpl(); webSSOProfile.setProcessor(samlProcessor); return webSSOProfile; } @Bean public WebSSOProfileECPImpl ecpprofile() { return new WebSSOProfileECPImpl(); } }