@Override public SignableXMLObject setSignature( SignableXMLObject signableXMLObject, String signatureAlgorithm, String digestAlgorithm, X509Credential cred) throws IdentityException { Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); signature.setSigningCredential(cred); signature.setSignatureAlgorithm(signatureAlgorithm); signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME); X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME); X509Certificate cert = (X509Certificate) buildXMLObject(X509Certificate.DEFAULT_ELEMENT_NAME); String value; try { value = org.apache.xml.security.utils.Base64.encode(cred.getEntityCertificate().getEncoded()); } catch (CertificateEncodingException e) { throw IdentityException.error("Error occurred while retrieving encoded cert", e); } cert.setValue(value); data.getX509Certificates().add(cert); keyInfo.getX509Datas().add(data); signature.setKeyInfo(keyInfo); signableXMLObject.setSignature(signature); ((SAMLObjectContentReference) signature.getContentReferences().get(0)) .setDigestAlgorithm(digestAlgorithm); List<Signature> signatureList = new ArrayList<Signature>(); signatureList.add(signature); MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(signableXMLObject); try { marshaller.marshall(signableXMLObject); } catch (MarshallingException e) { throw IdentityException.error("Unable to marshall the request", e); } org.apache.xml.security.Init.init(); try { Signer.signObjects(signatureList); } catch (SignatureException e) { throw IdentityException.error("Error occurred while signing request", e); } return signableXMLObject; }
/** * Based on the settings in the extended metadata either creates a PKIX trust engine with trusted * keys specified in the extended metadata as anchors or (by default) an explicit trust engine * using data from the metadata or from the values overridden in the ExtendedMetadata. * * @param samlContext context to populate */ protected void populateTrustEngine(SAMLMessageContext samlContext) { SignatureTrustEngine engine; if ("pkix".equalsIgnoreCase(samlContext.getLocalExtendedMetadata().getSecurityProfile())) { engine = new PKIXSignatureTrustEngine( pkixResolver, Configuration.getGlobalSecurityConfiguration().getDefaultKeyInfoCredentialResolver()); } else { engine = new ExplicitKeySignatureTrustEngine( metadataResolver, Configuration.getGlobalSecurityConfiguration().getDefaultKeyInfoCredentialResolver()); } samlContext.setLocalTrustEngine(engine); }
/** * Serialize the Auth. Request * * @param xmlObject * @return serialized auth. req */ protected String marshall(XMLObject xmlObject) throws SSOAgentException { try { System.setProperty( "javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); Element element = marshaller.marshall(xmlObject); ByteArrayOutputStream byteArrayOutputStrm = new ByteArrayOutputStream(); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); LSSerializer writer = impl.createLSSerializer(); LSOutput output = impl.createLSOutput(); output.setByteStream(byteArrayOutputStrm); writer.write(element, output); return new String(byteArrayOutputStrm.toByteArray(), Charset.forName("UTF-8")); } catch (ClassNotFoundException e) { throw new SSOAgentException("Error in marshalling SAML2 Assertion", e); } catch (InstantiationException e) { throw new SSOAgentException("Error in marshalling SAML2 Assertion", e); } catch (MarshallingException e) { throw new SSOAgentException("Error in marshalling SAML2 Assertion", e); } catch (IllegalAccessException e) { throw new SSOAgentException("Error in marshalling SAML2 Assertion", e); } }
/** * Applies the XML Digital Signature to the SAML 2.0 based Logout Request (LogoutRequest). * * @param logoutRequest the SAML 2.0 based Logout Request (LogoutRequest) * @param signatureAlgorithm the algorithm used to compute the signature * @param credential the signature signing credential * @return the SAML 2.0 based Logout Request (LogoutRequest) with XML Digital Signature set * @throws SSOException if an error occurs while signing the SAML 2.0 LogoutRequest message */ protected static LogoutRequest setSignature( LogoutRequest logoutRequest, String signatureAlgorithm, X509Credential credential) throws SSOException { try { Signature signature = setSignatureRaw(signatureAlgorithm, credential); logoutRequest.setSignature(signature); List<Signature> signatureList = new ArrayList<>(); signatureList.add(signature); // Marshall and Sign MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(logoutRequest); marshaller.marshall(logoutRequest); // Initializes and configures the library Init.init(); // Signer is responsible for creating the digital signatures for the given XML Objects. // Signs the XML Objects based on the given order of the Signature list Signer.signObjects(signatureList); return logoutRequest; } catch (MarshallingException | SignatureException e) { throw new SSOException("Error while signing the SAML 2.0 based LogoutRequest message", e); } }
private static String getMetadataAsString(final EntityDescriptor descriptor) throws MarshallingException { final MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory(); final Marshaller marshaller = marshallerFactory.getMarshaller(descriptor); final Element element = marshaller.marshall(descriptor); return XMLHelper.nodeToString(element); }
private void initSAML2() throws ConfigurationException, ConfigXMLParsingException, MetadataProviderException { if (logger.isDebugEnabled()) { logger.debug("initSAML2() - start"); // $NON-NLS-1$ } // // One-time init code here // DefaultBootstrap.bootstrap(); StorageService<String, ReplayCacheEntry> storageEngine = new MapBasedStorageService<String, ReplayCacheEntry>(); ReplayCache replayCache = new ReplayCache(storageEngine, 60 * 1000 * replayMinutes); replayRule = new MessageReplayRule(replayCache); // Get the private key that corresponds to a public key that may // have been used by other parties for encryption Credential decryptionCredential = getDecryptionCredential(decryptionKey.getKeystore(), localEntityId); List<Credential> localCredentials = new ArrayList<Credential>(); localCredentials.add(decryptionCredential); CollectionCredentialResolver localCredResolver = new CollectionCredentialResolver(localCredentials); // Support EncryptedKey/KeyInfo containing decryption key hints via // KeyValue/RSAKeyValue and X509Data/X509Certificate List<KeyInfoProvider> kiProviders = new ArrayList<KeyInfoProvider>(); kiProviders.add(new RSAKeyValueProvider()); kiProviders.add(new InlineX509DataProvider()); // Resolves local credentials by using information in the EncryptedKey/KeyInfo to query the // supplied // local credential resolver. kekResolver = new LocalKeyInfoCredentialResolver(kiProviders, localCredResolver); // Supports resolution of EncryptedKeys by 3 common placement mechanisms encryptedKeyResolver = new ChainingEncryptedKeyResolver(); encryptedKeyResolver.getResolverChain().add(new InlineEncryptedKeyResolver()); encryptedKeyResolver.getResolverChain().add(new EncryptedElementTypeEncryptedKeyResolver()); encryptedKeyResolver.getResolverChain().add(new SimpleRetrievalMethodEncryptedKeyResolver()); // siginingCredential = // getVerificationCredential(signingKey.getKeystore(),signingKey.getEntityId()); MetadataProvider mdProvider = getMetadataProvider(); MetadataCredentialResolver mdCredResolver = new MetadataCredentialResolver(mdProvider); KeyInfoCredentialResolver keyInfoCredResolver = Configuration.getGlobalSecurityConfiguration().getDefaultKeyInfoCredentialResolver(); trustEngine = new CustomKeySignatureTrustEngine(mdCredResolver, keyInfoCredResolver); if (logger.isDebugEnabled()) { logger.debug("initSAML2() - end"); // $NON-NLS-1$ } }
/** * Builds SAML Elements * * @param objectQName * @return * @throws IdentityException */ private XMLObject buildXMLObject(QName objectQName) throws IdentityException { XMLObjectBuilder builder = org.opensaml.xml.Configuration.getBuilderFactory().getBuilder(objectQName); if (builder == null) { throw IdentityException.error("Unable to retrieve builder for object QName " + objectQName); } return builder.buildObject( objectQName.getNamespaceURI(), objectQName.getLocalPart(), objectQName.getPrefix()); }
/* * Create the AuthnRequest */ public AuthnRequestImpl buildAuthnRequest() throws ValidationException { // Use the OpenSAML Configuration singleton to get a builder factory object final XMLObjectBuilderFactory xmlObjectBuilderFactory = Configuration.getBuilderFactory(); // First get a builder for AuthnRequest final AuthnRequestBuilder authnRequestBuilder = (AuthnRequestBuilder) xmlObjectBuilderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME); // And one for Issuer final IssuerBuilder issuerBuilder = (IssuerBuilder) xmlObjectBuilderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME); // get a builder for NameID final NameIDBuilder nameIDBuilder = (NameIDBuilder) xmlObjectBuilderFactory.getBuilder(NameID.DEFAULT_ELEMENT_NAME); // build a NameID object final NameID nameID = nameIDBuilder.buildObject(); nameID.setFormat(NameIDType.PERSISTENT); nameID.setSPProvidedID("https://aa.bb.cc/sp/provider"); nameID.setSPNameQualifier("https://aa.bb.cc/sp/provider"); // get a builder for Subject final SubjectBuilder subjectBuilder = (SubjectBuilder) xmlObjectBuilderFactory.getBuilder(Subject.DEFAULT_ELEMENT_NAME); // build a Subject object final Subject subject = subjectBuilder.buildObject(); subject.setNameID(nameID); // build an AuthnRequest object final AuthnRequestImpl authnRequest = (AuthnRequestImpl) authnRequestBuilder.buildObject(); // Build the Issuer object final Issuer newIssuer = issuerBuilder.buildObject(); newIssuer.setValue("https://aa.bb.cc/sp/provideraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); authnRequest.setIssuer(newIssuer); authnRequest.setProviderName("https://aa.bb.cc/sp/provider"); authnRequest.setAssertionConsumerServiceURL("1"); authnRequest.setDestination("https://aa.bb.cc/sp/provider"); authnRequest.setProtocolBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); authnRequest.setSubject(subject); // Only add the parameter if it is true. // if (forceReAuthentication == true) { authnRequest.setForceAuthn(true); // } authnRequest.setVersion(org.opensaml.common.SAMLVersion.VERSION_20); final DateTime dateTime = new DateTime(); authnRequest.setIssueInstant(dateTime); authnRequest.setID(UUID.randomUUID().toString()); authnRequest.validate(true); return authnRequest; }
/** * Builds a SAML 2.0 based XML object using the fully qualified name. * * @param objectQualifiedName fully qualified name * @return a SAML 2.0 based XML object * @throws SSOException if an error occurs while retrieving the builder for the fully qualified * name */ private static XMLObject buildXMLObject(QName objectQualifiedName) throws SSOException { doBootstrap(); XMLObjectBuilder builder = org.opensaml.xml.Configuration.getBuilderFactory().getBuilder(objectQualifiedName); if (!Optional.ofNullable(builder).isPresent()) { throw new SSOException("Unable to retrieve builder for object QName " + objectQualifiedName); } return builder.buildObject( objectQualifiedName.getNamespaceURI(), objectQualifiedName.getLocalPart(), objectQualifiedName.getPrefix()); }
private static void bootstrap() throws ConfigurationException { PaosBootstrap.bootstrap(); NamedKeyInfoGeneratorManager manager = Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager(); X509KeyInfoGeneratorFactory generator = new X509KeyInfoGeneratorFactory(); generator.setEmitEntityCertificate(true); generator.setEmitEntityCertificateChain(true); manager.registerFactory( org.springframework.security.saml.SAMLConstants.SAML_METADATA_KEY_INFO_GENERATOR, generator); }
/* * Create a fully formed SAML Request. * @return The SAML Request as XML. */ public String buildAuthnRequest2String() throws org.opensaml.xml.io.MarshallingException, BindingException, IOException, ValidationException { // build an AuthnRequest object final AuthnRequestImpl auth = buildAuthnRequest(); // Now we must marshall the object for the transfer over the wire. final Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(auth); final Element authDOM = marshaller.marshall(auth); // We use a StringWriter to produce our XML output. This gets us XML where // the encoding is UTF-8. We must have UTF-8 or bad things happen. return XMLHelper.prettyPrintXML(authDOM); }
/** * Sign the SAML AuthnRequest message * * @param logoutRequest * @param signatureAlgorithm * @param cred * @return * @throws SAMLSSOException */ public static LogoutRequest setSignature( LogoutRequest logoutRequest, String signatureAlgorithm, X509Credential cred) throws SAMLSSOException { try { Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); signature.setSigningCredential(cred); signature.setSignatureAlgorithm(signatureAlgorithm); signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); try { KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME); X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME); org.opensaml.xml.signature.X509Certificate cert = (org.opensaml.xml.signature.X509Certificate) buildXMLObject(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME); String value = org.apache.xml.security.utils.Base64.encode(cred.getEntityCertificate().getEncoded()); cert.setValue(value); data.getX509Certificates().add(cert); keyInfo.getX509Datas().add(data); signature.setKeyInfo(keyInfo); } catch (CertificateEncodingException e) { throw new SAMLSSOException("Error getting certificate", e); } logoutRequest.setSignature(signature); List<Signature> signatureList = new ArrayList<Signature>(); signatureList.add(signature); // Marshall and Sign MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(logoutRequest); marshaller.marshall(logoutRequest); org.apache.xml.security.Init.init(); Signer.signObjects(signatureList); return logoutRequest; } catch (Exception e) { throw new SAMLSSOException("Error while signing the Logout Request message", e); } }
/** * Gets the signature algorithm URI to use with the given signing credential. * * @param credential the credential that will be used to sign the message * @param config the SecurityConfiguration to use (may be null) * @return signature algorithm to use with the given signing credential * @throws MessageEncodingException thrown if the algorithm URI could not be derived from the * supplied credential */ protected String getSignatureAlgorithmURI(Credential credential, SecurityConfiguration config) throws MessageEncodingException { SecurityConfiguration secConfig; if (config != null) { secConfig = config; } else { secConfig = Configuration.getGlobalSecurityConfiguration(); } String signAlgo = secConfig.getSignatureAlgorithmURI(credential); if (signAlgo == null) { throw new MessageEncodingException( "The signing credential's algorithm URI could not be derived"); } return signAlgo; }
/** * Serializing a SAML2 object into a String * * @param xmlObject object that needs to serialized. * @return serialized object * @throws Exception */ public static String marshall(XMLObject xmlObject) throws Exception { try { doBootstrap(); System.setProperty( "javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); Element element = marshaller.marshall(xmlObject); ByteArrayOutputStream byteArrayOutputStrm = new ByteArrayOutputStream(); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); LSSerializer writer = impl.createLSSerializer(); LSOutput output = impl.createLSOutput(); output.setByteStream(byteArrayOutputStrm); writer.write(element, output); return byteArrayOutputStrm.toString(); } catch (Exception e) { throw new Exception("Error Serializing the SAML Response", e); } }