use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class XMLEncryptionUtil method encryptElementInDocument.
/**
* Encrypt the root document element inside a Document. <b>NOTE:</b> The document root element will be replaced by
* the
* wrapping element.
*
* @param document Document that contains an element to encrypt
* @param publicKey The Public Key used to encrypt the secret encryption key
* @param secretKey The secret encryption key
* @param keySize Length of key
* @param wrappingElementQName QName of the element to be used to wrap around the cipher data.
* @param addEncryptedKeyInKeyInfo Should the encrypted key be inside a KeyInfo or added as a peer of Cipher Data
*
* @return An element that has the wrappingElementQName
*
* @throws ProcessingException
* @throws org.keycloak.saml.common.exceptions.ConfigurationException
*/
public static Element encryptElementInDocument(Document document, PublicKey publicKey, SecretKey secretKey, int keySize, QName wrappingElementQName, boolean addEncryptedKeyInKeyInfo) throws ProcessingException, ConfigurationException {
String wrappingElementPrefix = wrappingElementQName.getPrefix();
if (wrappingElementPrefix == null || "".equals(wrappingElementPrefix))
throw logger.wrongTypeError("Wrapping element prefix invalid");
XMLCipher cipher = null;
EncryptedKey encryptedKey = encryptKey(document, secretKey, publicKey, keySize);
String encryptionAlgorithm = getXMLEncryptionURL(secretKey.getAlgorithm(), keySize);
// Encrypt the Document
try {
cipher = XMLCipher.getInstance(encryptionAlgorithm);
cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
} catch (XMLEncryptionException e1) {
throw logger.configurationError(e1);
}
Document encryptedDoc;
try {
encryptedDoc = cipher.doFinal(document, document.getDocumentElement());
} catch (Exception e) {
throw logger.processingError(e);
}
// The EncryptedKey element is added
Element encryptedKeyElement = cipher.martial(document, encryptedKey);
final String wrappingElementName;
if (StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
wrappingElementName = wrappingElementQName.getLocalPart();
} else {
wrappingElementName = wrappingElementPrefix + ":" + wrappingElementQName.getLocalPart();
}
// Create the wrapping element and set its attribute NS
Element wrappingElement = encryptedDoc.createElementNS(wrappingElementQName.getNamespaceURI(), wrappingElementName);
if (!StringUtil.isNullOrEmpty(wrappingElementPrefix)) {
wrappingElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + wrappingElementPrefix, wrappingElementQName.getNamespaceURI());
}
Element encryptedDocRootElement = encryptedDoc.getDocumentElement();
// Bring in the encrypted wrapping element to wrap the root node
encryptedDoc.replaceChild(wrappingElement, encryptedDocRootElement);
wrappingElement.appendChild(encryptedDocRootElement);
if (addEncryptedKeyInKeyInfo) {
// Outer ds:KeyInfo Element to hold the EncryptionKey
Element sigElement = encryptedDoc.createElementNS(XMLSignature.XMLNS, DS_KEY_INFO);
sigElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:ds", XMLSignature.XMLNS);
sigElement.appendChild(encryptedKeyElement);
// Insert the Encrypted key before the CipherData element
NodeList nodeList = encryptedDocRootElement.getElementsByTagNameNS(EncryptionConstants.EncryptionSpecNS, EncryptionConstants._TAG_CIPHERDATA);
if (nodeList == null || nodeList.getLength() == 0)
throw logger.domMissingElementError("xenc:CipherData");
Element cipherDataElement = (Element) nodeList.item(0);
encryptedDocRootElement.insertBefore(sigElement, cipherDataElement);
} else {
// Add the encrypted key as a child of the wrapping element
wrappingElement.appendChild(encryptedKeyElement);
}
return encryptedDoc.getDocumentElement();
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class CreateAuthnRequestStepBuilder method createLoginRequestDocument.
protected Document createLoginRequestDocument() {
if (this.forceLoginRequestDocument != null) {
return this.forceLoginRequestDocument;
}
try {
SAML2Request samlReq = new SAML2Request();
AuthnRequestType loginReq = samlReq.createAuthnRequestType(UUID.randomUUID().toString(), assertionConsumerURL, this.authServerSamlUrl.toString(), issuer, requestBinding.getBindingUri());
if (protocolBinding != null) {
loginReq.setProtocolBinding(protocolBinding);
}
return SAML2Request.convert(loginReq);
} catch (ConfigurationException | ParsingException | ProcessingException ex) {
throw new RuntimeException(ex);
}
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class ArtifactResolutionService method invoke.
/**
* This is the method called when a message is received by the endpoint.
* It gets the message, extracts the ArtifactResolve message from the SOAP, creates a SOAP message containing
* an ArtifactResponse message with the configured SAML message, and returns it.
* @param msg The SOAP message received by the endpoint, in Source format
* @return A StreamSource containing the ArtifactResponse
*/
@Override
public Source invoke(Source msg) {
byte[] response;
try (StringWriter w = new StringWriter()) {
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(msg, new StreamResult(w));
String s = w.toString();
Document doc = Soap.extractSoapMessage(new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8)));
SAMLDocumentHolder samlDoc = SAML2Request.getSAML2ObjectFromDocument(doc);
if (samlDoc.getSamlObject() instanceof ArtifactResolveType) {
lastArtifactResolve = (ArtifactResolveType) samlDoc.getSamlObject();
} else {
lastArtifactResolve = null;
}
Document artifactResponse = SamlProtocolUtils.convert(artifactResponseType);
response = Soap.createMessage().addToBody(artifactResponse).getBytes();
} catch (ProcessingException | ConfigurationException | TransformerException | ParsingException | IOException e) {
throw new RuntimeException(e);
}
return new StreamSource(new ByteArrayInputStream(response));
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class KcSamlEncryptedIdTest method testEncryptedIdIsReadable.
@Test
public void testEncryptedIdIsReadable() throws ConfigurationException, ParsingException, ProcessingException {
createRolesForRealm(bc.consumerRealmName());
AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(SAML_CLIENT_ID_SALES_POST + ".dot/ted", getConsumerRoot() + "/sales-post/saml", null);
Document doc = SAML2Request.convert(loginRep);
final AtomicReference<String> username = new AtomicReference<>();
assertThat(adminClient.realm(bc.consumerRealmName()).users().search(username.get()), hasSize(0));
SAMLDocumentHolder samlResponse = new SamlClientBuilder().authnRequest(getConsumerSamlEndpoint(bc.consumerRealmName()), doc, SamlClient.Binding.POST).build().login().idp(bc.getIDPAlias()).build().processSamlResponse(// AuthnRequest to producer IdP
SamlClient.Binding.POST).targetAttributeSamlRequest().build().login().user(bc.getUserLogin(), bc.getUserPassword()).build().processSamlResponse(// Response from producer IdP
SamlClient.Binding.POST).transformDocument(document -> {
// Replace Subject -> NameID with EncryptedId
Node assertionElement = document.getDocumentElement().getElementsByTagNameNS(ASSERTION_NSURI.get(), JBossSAMLConstants.ASSERTION.get()).item(0);
if (assertionElement == null) {
throw new IllegalStateException("Unable to find assertion in saml response document");
}
String samlNSPrefix = assertionElement.getPrefix();
try {
QName encryptedIdElementQName = new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.ENCRYPTED_ID.get(), samlNSPrefix);
QName nameIdQName = new QName(ASSERTION_NSURI.get(), JBossSAMLConstants.NAMEID.get(), samlNSPrefix);
// Add xmlns:saml attribute to NameId element,
// this is necessary as it is decrypted as a separate doc and saml namespace is not know
// unless added to NameId element
Element nameIdElement = DocumentUtil.getElement(document, nameIdQName);
if (nameIdElement == null) {
throw new RuntimeException("Assertion doesn't contain NameId " + DocumentUtil.asString(document));
}
nameIdElement.setAttribute("xmlns:" + samlNSPrefix, ASSERTION_NSURI.get());
username.set(nameIdElement.getTextContent());
byte[] secret = RandomSecret.createRandomSecret(128 / 8);
SecretKey secretKey = new SecretKeySpec(secret, "AES");
// encrypt the Assertion element and replace it with a EncryptedAssertion element.
XMLEncryptionUtil.encryptElement(nameIdQName, document, PemUtils.decodePublicKey(ApiUtil.findActiveSigningKey(adminClient.realm(bc.consumerRealmName())).getPublicKey()), secretKey, 128, encryptedIdElementQName, true);
} catch (Exception e) {
throw new ProcessingException("failed to encrypt", e);
}
assertThat(DocumentUtil.asString(document), not(containsString(username.get())));
return document;
}).build().updateProfile().firstName("a").lastName("b").email(bc.getUserEmail()).build().followOneRedirect().getSamlResponse(// Response from consumer IdP
SamlClient.Binding.POST);
assertThat(samlResponse, Matchers.notNullValue());
assertThat(samlResponse.getSamlObject(), isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
assertThat(adminClient.realm(bc.consumerRealmName()).users().search(username.get()), hasSize(1));
}
use of org.keycloak.saml.common.exceptions.ProcessingException in project keycloak by keycloak.
the class LogoutTest method createAuthnResponse.
private SAML2Object createAuthnResponse(SAML2Object so) {
AuthnRequestType req = (AuthnRequestType) so;
try {
final ResponseType res = new SAML2LoginResponseBuilder().requestID(req.getID()).destination(req.getAssertionConsumerServiceURL().toString()).issuer(BROKER_SERVICE_ID).assertionExpiration(1000000).subjectExpiration(1000000).requestIssuer(getAuthServerRealmBase(REALM_NAME).toString()).nameIdentifier(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get(), "a@b.c").authMethod(JBossSAMLURIConstants.AC_UNSPECIFIED.get()).sessionIndex("idp:" + UUID.randomUUID()).buildModel();
NameIDType nameId = (NameIDType) res.getAssertions().get(0).getAssertion().getSubject().getSubType().getBaseID();
nameId.setNameQualifier(NAME_QUALIFIER);
nameId.setSPNameQualifier(SP_NAME_QUALIFIER);
nameId.setSPProvidedID(SP_PROVIDED_ID);
return res;
} catch (ConfigurationException | ProcessingException ex) {
throw new RuntimeException(ex);
}
}
Aggregations