KEYCLOAK-4057 Do not include KeyName for brokered IdPs
Active Directory Federation Services require that the subject name matches KeyName element when present. While KeyName is beneficial for Keycloak adapters, it breaks functionality for AD FS as the name included there is a key ID, not certificate subject expected by AD FS. This patch contains functionality that excludes KeyName from SAML messages to identity providers. This behaviour should be made configurable per client/identity provider and is prepared to do so, however actual GUI changes are left for a separate patch.
This commit is contained in:
parent
d3e3990d77
commit
24a36e6848
12 changed files with 156 additions and 50 deletions
|
@ -58,7 +58,7 @@ import static org.keycloak.saml.common.util.StringUtil.isNotNull;
|
||||||
public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
protected static final Logger logger = Logger.getLogger(BaseSAML2BindingBuilder.class);
|
protected static final Logger logger = Logger.getLogger(BaseSAML2BindingBuilder.class);
|
||||||
|
|
||||||
protected String signingKeyId;
|
protected String signingKeyName;
|
||||||
protected KeyPair signingKeyPair;
|
protected KeyPair signingKeyPair;
|
||||||
protected X509Certificate signingCertificate;
|
protected X509Certificate signingCertificate;
|
||||||
protected boolean sign;
|
protected boolean sign;
|
||||||
|
@ -86,27 +86,27 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T signWith(String signingKeyId, KeyPair keyPair) {
|
public T signWith(String signingKeyName, KeyPair keyPair) {
|
||||||
this.signingKeyId = signingKeyId;
|
this.signingKeyName = signingKeyName;
|
||||||
this.signingKeyPair = keyPair;
|
this.signingKeyPair = keyPair;
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T signWith(String signingKeyId, PrivateKey privateKey, PublicKey publicKey) {
|
public T signWith(String signingKeyName, PrivateKey privateKey, PublicKey publicKey) {
|
||||||
this.signingKeyId = signingKeyId;
|
this.signingKeyName = signingKeyName;
|
||||||
this.signingKeyPair = new KeyPair(publicKey, privateKey);
|
this.signingKeyPair = new KeyPair(publicKey, privateKey);
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T signWith(String signingKeyId, KeyPair keyPair, X509Certificate cert) {
|
public T signWith(String signingKeyName, KeyPair keyPair, X509Certificate cert) {
|
||||||
this.signingKeyId = signingKeyId;
|
this.signingKeyName = signingKeyName;
|
||||||
this.signingKeyPair = keyPair;
|
this.signingKeyPair = keyPair;
|
||||||
this.signingCertificate = cert;
|
this.signingCertificate = cert;
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T signWith(String signingKeyId, PrivateKey privateKey, PublicKey publicKey, X509Certificate cert) {
|
public T signWith(String signingKeyName, PrivateKey privateKey, PublicKey publicKey, X509Certificate cert) {
|
||||||
this.signingKeyId = signingKeyId;
|
this.signingKeyName = signingKeyName;
|
||||||
this.signingKeyPair = new KeyPair(publicKey, privateKey);
|
this.signingKeyPair = new KeyPair(publicKey, privateKey);
|
||||||
this.signingCertificate = cert;
|
this.signingCertificate = cert;
|
||||||
return (T)this;
|
return (T)this;
|
||||||
|
@ -271,7 +271,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
samlSignature.setX509Certificate(signingCertificate);
|
samlSignature.setX509Certificate(signingCertificate);
|
||||||
}
|
}
|
||||||
|
|
||||||
samlSignature.signSAMLDocument(samlDocument, signingKeyId, signingKeyPair, canonicalizationMethodType);
|
samlSignature.signSAMLDocument(samlDocument, signingKeyName, signingKeyPair, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signAssertion(Document samlDocument) throws ProcessingException {
|
public void signAssertion(Document samlDocument) throws ProcessingException {
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.keycloak.saml.common.util;
|
||||||
|
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hmlnarik
|
||||||
|
*/
|
||||||
|
public enum XmlKeyInfoKeyNameTransformer {
|
||||||
|
NONE { @Override public String getKeyName(String keyId, X509Certificate certificate) { return null; } },
|
||||||
|
KEY_ID { @Override public String getKeyName(String keyId, X509Certificate certificate) { return keyId; } },
|
||||||
|
CERT_SUBJECT { @Override public String getKeyName(String keyId, X509Certificate certificate) {
|
||||||
|
return certificate == null
|
||||||
|
? null
|
||||||
|
: (certificate.getSubjectDN() == null
|
||||||
|
? null
|
||||||
|
: certificate.getSubjectDN().getName());
|
||||||
|
} }
|
||||||
|
;
|
||||||
|
|
||||||
|
public abstract String getKeyName(String keyId, X509Certificate certificate);
|
||||||
|
|
||||||
|
public static XmlKeyInfoKeyNameTransformer from(String name, XmlKeyInfoKeyNameTransformer defaultValue) {
|
||||||
|
if (name == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return valueOf(name);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ public class SAML2Signature {
|
||||||
* @throws MarshalException
|
* @throws MarshalException
|
||||||
* @throws GeneralSecurityException
|
* @throws GeneralSecurityException
|
||||||
*/
|
*/
|
||||||
public Document sign(Document doc, String referenceID, String keyId, KeyPair keyPair, String canonicalizationMethodType) throws ParserConfigurationException,
|
public Document sign(Document doc, String referenceID, String keyName, KeyPair keyPair, String canonicalizationMethodType) throws ParserConfigurationException,
|
||||||
GeneralSecurityException, MarshalException, XMLSignatureException {
|
GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
String referenceURI = "#" + referenceID;
|
String referenceURI = "#" + referenceID;
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ public class SAML2Signature {
|
||||||
if (sibling != null) {
|
if (sibling != null) {
|
||||||
SignatureUtilTransferObject dto = new SignatureUtilTransferObject();
|
SignatureUtilTransferObject dto = new SignatureUtilTransferObject();
|
||||||
dto.setDocumentToBeSigned(doc);
|
dto.setDocumentToBeSigned(doc);
|
||||||
dto.setKeyId(keyId);
|
dto.setKeyName(keyName);
|
||||||
dto.setKeyPair(keyPair);
|
dto.setKeyPair(keyPair);
|
||||||
dto.setDigestMethod(digestMethod);
|
dto.setDigestMethod(digestMethod);
|
||||||
dto.setSignatureMethod(signatureMethod);
|
dto.setSignatureMethod(signatureMethod);
|
||||||
|
@ -143,7 +143,7 @@ public class SAML2Signature {
|
||||||
|
|
||||||
return XMLSignatureUtil.sign(dto, canonicalizationMethodType);
|
return XMLSignatureUtil.sign(dto, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
return XMLSignatureUtil.sign(doc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, canonicalizationMethodType);
|
return XMLSignatureUtil.sign(doc, keyName, keyPair, digestMethod, signatureMethod, referenceURI, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,11 +154,11 @@ public class SAML2Signature {
|
||||||
*
|
*
|
||||||
* @throws org.keycloak.saml.common.exceptions.ProcessingException
|
* @throws org.keycloak.saml.common.exceptions.ProcessingException
|
||||||
*/
|
*/
|
||||||
public void signSAMLDocument(Document samlDocument, String keyId, KeyPair keypair, String canonicalizationMethodType) throws ProcessingException {
|
public void signSAMLDocument(Document samlDocument, String keyName, KeyPair keypair, String canonicalizationMethodType) throws ProcessingException {
|
||||||
// Get the ID from the root
|
// Get the ID from the root
|
||||||
String id = samlDocument.getDocumentElement().getAttribute(ID_ATTRIBUTE_NAME);
|
String id = samlDocument.getDocumentElement().getAttribute(ID_ATTRIBUTE_NAME);
|
||||||
try {
|
try {
|
||||||
sign(samlDocument, id, keyId, keypair, canonicalizationMethodType);
|
sign(samlDocument, id, keyName, keypair, canonicalizationMethodType);
|
||||||
} catch (ParserConfigurationException | GeneralSecurityException | MarshalException | XMLSignatureException e) {
|
} catch (ParserConfigurationException | GeneralSecurityException | MarshalException | XMLSignatureException e) {
|
||||||
throw new ProcessingException(logger.signatureError(e));
|
throw new ProcessingException(logger.signatureError(e));
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class SignatureUtilTransferObject {
|
||||||
|
|
||||||
private Document documentToBeSigned;
|
private Document documentToBeSigned;
|
||||||
|
|
||||||
private String keyId;
|
private String keyName;
|
||||||
|
|
||||||
private KeyPair keyPair;
|
private KeyPair keyPair;
|
||||||
|
|
||||||
|
@ -115,11 +115,11 @@ public class SignatureUtilTransferObject {
|
||||||
this.x509Certificate = x509Certificate;
|
this.x509Certificate = x509Certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKeyId() {
|
public String getKeyName() {
|
||||||
return keyId;
|
return keyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyId(String keyId) {
|
public void setKeyName(String keyName) {
|
||||||
this.keyId = keyId;
|
this.keyName = keyName;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -216,7 +216,7 @@ public class XMLSignatureUtil {
|
||||||
* @throws MarshalException
|
* @throws MarshalException
|
||||||
* @throws GeneralSecurityException
|
* @throws GeneralSecurityException
|
||||||
*/
|
*/
|
||||||
public static Document sign(Document doc, Node nodeToBeSigned, String keyId, KeyPair keyPair, String digestMethod,
|
public static Document sign(Document doc, Node nodeToBeSigned, String keyName, KeyPair keyPair, String digestMethod,
|
||||||
String signatureMethod, String referenceURI, X509Certificate x509Certificate,
|
String signatureMethod, String referenceURI, X509Certificate x509Certificate,
|
||||||
String canonicalizationMethodType) throws ParserConfigurationException, GeneralSecurityException,
|
String canonicalizationMethodType) throws ParserConfigurationException, GeneralSecurityException,
|
||||||
MarshalException, XMLSignatureException {
|
MarshalException, XMLSignatureException {
|
||||||
|
@ -238,7 +238,7 @@ public class XMLSignatureUtil {
|
||||||
if (!referenceURI.isEmpty()) {
|
if (!referenceURI.isEmpty()) {
|
||||||
propagateIDAttributeSetup(nodeToBeSigned, newDoc.getDocumentElement());
|
propagateIDAttributeSetup(nodeToBeSigned, newDoc.getDocumentElement());
|
||||||
}
|
}
|
||||||
newDoc = sign(newDoc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, x509Certificate, canonicalizationMethodType);
|
newDoc = sign(newDoc, keyName, keyPair, digestMethod, signatureMethod, referenceURI, x509Certificate, canonicalizationMethodType);
|
||||||
|
|
||||||
// if the signed element is a SAMLv2.0 assertion we need to move the signature element to the position
|
// if the signed element is a SAMLv2.0 assertion we need to move the signature element to the position
|
||||||
// specified in the schema (before the assertion subject element).
|
// specified in the schema (before the assertion subject element).
|
||||||
|
@ -279,10 +279,10 @@ public class XMLSignatureUtil {
|
||||||
* @throws MarshalException
|
* @throws MarshalException
|
||||||
* @throws XMLSignatureException
|
* @throws XMLSignatureException
|
||||||
*/
|
*/
|
||||||
public static void sign(Element elementToSign, Node nextSibling, String keyId, KeyPair keyPair, String digestMethod,
|
public static void sign(Element elementToSign, Node nextSibling, String keyName, KeyPair keyPair, String digestMethod,
|
||||||
String signatureMethod, String referenceURI, String canonicalizationMethodType)
|
String signatureMethod, String referenceURI, String canonicalizationMethodType)
|
||||||
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
sign(elementToSign, nextSibling, keyId, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
|
sign(elementToSign, nextSibling, keyName, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -301,7 +301,7 @@ public class XMLSignatureUtil {
|
||||||
* @throws XMLSignatureException
|
* @throws XMLSignatureException
|
||||||
* @since 2.5.0
|
* @since 2.5.0
|
||||||
*/
|
*/
|
||||||
public static void sign(Element elementToSign, Node nextSibling, String keyId, KeyPair keyPair, String digestMethod,
|
public static void sign(Element elementToSign, Node nextSibling, String keyName, KeyPair keyPair, String digestMethod,
|
||||||
String signatureMethod, String referenceURI, X509Certificate x509Certificate, String canonicalizationMethodType)
|
String signatureMethod, String referenceURI, X509Certificate x509Certificate, String canonicalizationMethodType)
|
||||||
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
PrivateKey signingKey = keyPair.getPrivate();
|
PrivateKey signingKey = keyPair.getPrivate();
|
||||||
|
@ -309,7 +309,7 @@ public class XMLSignatureUtil {
|
||||||
|
|
||||||
DOMSignContext dsc = new DOMSignContext(signingKey, elementToSign, nextSibling);
|
DOMSignContext dsc = new DOMSignContext(signingKey, elementToSign, nextSibling);
|
||||||
|
|
||||||
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyId, publicKey, x509Certificate, canonicalizationMethodType);
|
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyName, publicKey, x509Certificate, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -343,9 +343,9 @@ public class XMLSignatureUtil {
|
||||||
* @throws XMLSignatureException
|
* @throws XMLSignatureException
|
||||||
* @throws MarshalException
|
* @throws MarshalException
|
||||||
*/
|
*/
|
||||||
public static Document sign(Document doc, String keyId, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI, String canonicalizationMethodType)
|
public static Document sign(Document doc, String keyName, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI, String canonicalizationMethodType)
|
||||||
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
return sign(doc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
|
return sign(doc, keyName, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -363,7 +363,7 @@ public class XMLSignatureUtil {
|
||||||
* @throws MarshalException
|
* @throws MarshalException
|
||||||
* @since 2.5.0
|
* @since 2.5.0
|
||||||
*/
|
*/
|
||||||
public static Document sign(Document doc, String keyId, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI,
|
public static Document sign(Document doc, String keyName, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI,
|
||||||
X509Certificate x509Certificate, String canonicalizationMethodType)
|
X509Certificate x509Certificate, String canonicalizationMethodType)
|
||||||
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
logger.trace("Document to be signed=" + DocumentUtil.asString(doc));
|
logger.trace("Document to be signed=" + DocumentUtil.asString(doc));
|
||||||
|
@ -372,7 +372,7 @@ public class XMLSignatureUtil {
|
||||||
|
|
||||||
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
|
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
|
||||||
|
|
||||||
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyId, publicKey, x509Certificate, canonicalizationMethodType);
|
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyName, publicKey, x509Certificate, canonicalizationMethodType);
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ public class XMLSignatureUtil {
|
||||||
public static Document sign(SignatureUtilTransferObject dto, String canonicalizationMethodType) throws GeneralSecurityException, MarshalException,
|
public static Document sign(SignatureUtilTransferObject dto, String canonicalizationMethodType) throws GeneralSecurityException, MarshalException,
|
||||||
XMLSignatureException {
|
XMLSignatureException {
|
||||||
Document doc = dto.getDocumentToBeSigned();
|
Document doc = dto.getDocumentToBeSigned();
|
||||||
String keyId = dto.getKeyId();
|
String keyName = dto.getKeyName();
|
||||||
KeyPair keyPair = dto.getKeyPair();
|
KeyPair keyPair = dto.getKeyPair();
|
||||||
Node nextSibling = dto.getNextSibling();
|
Node nextSibling = dto.getNextSibling();
|
||||||
String digestMethod = dto.getDigestMethod();
|
String digestMethod = dto.getDigestMethod();
|
||||||
|
@ -404,7 +404,7 @@ public class XMLSignatureUtil {
|
||||||
|
|
||||||
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement(), nextSibling);
|
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement(), nextSibling);
|
||||||
|
|
||||||
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyId, publicKey, dto.getX509Certificate(), canonicalizationMethodType);
|
signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyName, publicKey, dto.getX509Certificate(), canonicalizationMethodType);
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ public class XMLSignatureUtil {
|
||||||
throw logger.unsupportedType(key.toString());
|
throw logger.unsupportedType(key.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void signImpl(DOMSignContext dsc, String digestMethod, String signatureMethod, String referenceURI, String keyId, PublicKey publicKey,
|
private static void signImpl(DOMSignContext dsc, String digestMethod, String signatureMethod, String referenceURI, String keyName, PublicKey publicKey,
|
||||||
X509Certificate x509Certificate, String canonicalizationMethodType)
|
X509Certificate x509Certificate, String canonicalizationMethodType)
|
||||||
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
throws GeneralSecurityException, MarshalException, XMLSignatureException {
|
||||||
dsc.setDefaultNamespacePrefix("dsig");
|
dsc.setDefaultNamespacePrefix("dsig");
|
||||||
|
@ -718,22 +718,22 @@ public class XMLSignatureUtil {
|
||||||
|
|
||||||
KeyInfo ki;
|
KeyInfo ki;
|
||||||
if (includeKeyInfoInSignature) {
|
if (includeKeyInfoInSignature) {
|
||||||
ki = createKeyInfo(keyId, publicKey, x509Certificate);
|
ki = createKeyInfo(keyName, publicKey, x509Certificate);
|
||||||
} else {
|
} else {
|
||||||
ki = createKeyInfo(keyId, null, null);
|
ki = createKeyInfo(keyName, null, null);
|
||||||
}
|
}
|
||||||
XMLSignature signature = fac.newXMLSignature(si, ki);
|
XMLSignature signature = fac.newXMLSignature(si, ki);
|
||||||
|
|
||||||
signature.sign(dsc);
|
signature.sign(dsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static KeyInfo createKeyInfo(String keyId, PublicKey publicKey, X509Certificate x509Certificate) throws KeyException {
|
private static KeyInfo createKeyInfo(String keyName, PublicKey publicKey, X509Certificate x509Certificate) throws KeyException {
|
||||||
KeyInfoFactory keyInfoFactory = fac.getKeyInfoFactory();
|
KeyInfoFactory keyInfoFactory = fac.getKeyInfoFactory();
|
||||||
|
|
||||||
List<Object> items = new LinkedList<>();
|
List<Object> items = new LinkedList<>();
|
||||||
|
|
||||||
if (keyId != null) {
|
if (keyName != null) {
|
||||||
items.add(keyInfoFactory.newKeyName(keyId));
|
items.add(keyInfoFactory.newKeyName(keyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x509Certificate != null) {
|
if (x509Certificate != null) {
|
||||||
|
|
|
@ -302,11 +302,12 @@ public class SAMLEndpoint {
|
||||||
boolean postBinding = config.isPostBindingResponse();
|
boolean postBinding = config.isPostBindingResponse();
|
||||||
if (config.isWantAuthnRequestsSigned()) {
|
if (config.isWantAuthnRequestsSigned()) {
|
||||||
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
||||||
binding.signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
|
String keyName = config.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
binding.signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
|
||||||
.signatureAlgorithm(provider.getSignatureAlgorithm())
|
.signatureAlgorithm(provider.getSignatureAlgorithm())
|
||||||
.signDocument();
|
.signDocument();
|
||||||
if (! postBinding && config.isAddExtensionsElementWithKeyInfo()) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
if (! postBinding && config.isAddExtensionsElementWithKeyInfo()) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
||||||
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keys.getKid()));
|
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -107,11 +107,12 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||||
|
|
||||||
KeyPair keypair = new KeyPair(keys.getPublicKey(), keys.getPrivateKey());
|
KeyPair keypair = new KeyPair(keys.getPublicKey(), keys.getPrivateKey());
|
||||||
|
|
||||||
binding.signWith(keys.getKid(), keypair);
|
String keyName = getConfig().getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
binding.signWith(keyName, keypair);
|
||||||
binding.signatureAlgorithm(getSignatureAlgorithm());
|
binding.signatureAlgorithm(getSignatureAlgorithm());
|
||||||
binding.signDocument();
|
binding.signDocument();
|
||||||
if (! postBinding && getConfig().isAddExtensionsElementWithKeyInfo()) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
if (! postBinding && getConfig().isAddExtensionsElementWithKeyInfo()) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
||||||
authnRequestBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keys.getKid()));
|
authnRequestBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +206,8 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
|
||||||
.relayState(userSession.getId());
|
.relayState(userSession.getId());
|
||||||
if (getConfig().isWantAuthnRequestsSigned()) {
|
if (getConfig().isWantAuthnRequestsSigned()) {
|
||||||
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
||||||
binding.signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
|
String keyName = getConfig().getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
binding.signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
|
||||||
.signatureAlgorithm(getSignatureAlgorithm())
|
.signatureAlgorithm(getSignatureAlgorithm())
|
||||||
.signDocument();
|
.signDocument();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,15 @@ package org.keycloak.broker.saml;
|
||||||
|
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
|
|
||||||
|
import org.keycloak.saml.common.util.XmlKeyInfoKeyNameTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pedro Igor
|
* @author Pedro Igor
|
||||||
*/
|
*/
|
||||||
public class SAMLIdentityProviderConfig extends IdentityProviderModel {
|
public class SAMLIdentityProviderConfig extends IdentityProviderModel {
|
||||||
|
|
||||||
|
public static final XmlKeyInfoKeyNameTransformer DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER = XmlKeyInfoKeyNameTransformer.NONE;
|
||||||
|
|
||||||
public SAMLIdentityProviderConfig() {
|
public SAMLIdentityProviderConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,4 +169,19 @@ public class SAMLIdentityProviderConfig extends IdentityProviderModel {
|
||||||
getConfig().put("backchannelSupported", String.valueOf(backchannel));
|
getConfig().put("backchannelSupported", String.valueOf(backchannel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always returns non-{@code null} result.
|
||||||
|
* @return Configured ransformer of {@link #DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER} if not set.
|
||||||
|
*/
|
||||||
|
public XmlKeyInfoKeyNameTransformer getXmlSigKeyInfoKeyNameTransformer() {
|
||||||
|
return XmlKeyInfoKeyNameTransformer.from(getConfig().get("xmlSigKeyInfoKeyNameTransformer"), DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXmlSigKeyInfoKeyNameTransformer(XmlKeyInfoKeyNameTransformer xmlSigKeyInfoKeyNameTransformer) {
|
||||||
|
getConfig().put("xmlSigKeyInfoKeyNameTransformer",
|
||||||
|
xmlSigKeyInfoKeyNameTransformer == null
|
||||||
|
? null
|
||||||
|
: xmlSigKeyInfoKeyNameTransformer.name());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.keycloak.models.ClientConfigResolver;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.saml.SignatureAlgorithm;
|
import org.keycloak.saml.SignatureAlgorithm;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
|
import org.keycloak.saml.common.util.XmlKeyInfoKeyNameTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration of a SAML-enabled client.
|
* Configuration of a SAML-enabled client.
|
||||||
|
@ -30,6 +31,8 @@ import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
*/
|
*/
|
||||||
public class SamlClient extends ClientConfigResolver {
|
public class SamlClient extends ClientConfigResolver {
|
||||||
|
|
||||||
|
public static final XmlKeyInfoKeyNameTransformer DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER = XmlKeyInfoKeyNameTransformer.KEY_ID;
|
||||||
|
|
||||||
public SamlClient(ClientModel client) {
|
public SamlClient(ClientModel client) {
|
||||||
super(client);
|
super(client);
|
||||||
}
|
}
|
||||||
|
@ -198,4 +201,21 @@ public class SamlClient extends ClientConfigResolver {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always returns non-{@code null} result.
|
||||||
|
* @return Configured ransformer of {@link #DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER} if not set.
|
||||||
|
*/
|
||||||
|
public XmlKeyInfoKeyNameTransformer getXmlSigKeyInfoKeyNameTransformer() {
|
||||||
|
return XmlKeyInfoKeyNameTransformer.from(
|
||||||
|
client.getAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER),
|
||||||
|
DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXmlSigKeyInfoKeyNameTransformer(XmlKeyInfoKeyNameTransformer xmlSigKeyInfoKeyNameTransformer) {
|
||||||
|
client.setAttribute(SamlConfigAttributes.SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER,
|
||||||
|
xmlSigKeyInfoKeyNameTransformer == null
|
||||||
|
? null
|
||||||
|
: xmlSigKeyInfoKeyNameTransformer.name());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public interface SamlConfigAttributes {
|
||||||
String SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE = "saml_force_name_id_format";
|
String SAML_FORCE_NAME_ID_FORMAT_ATTRIBUTE = "saml_force_name_id_format";
|
||||||
String SAML_SERVER_SIGNATURE = "saml.server.signature";
|
String SAML_SERVER_SIGNATURE = "saml.server.signature";
|
||||||
String SAML_SERVER_SIGNATURE_KEYINFO_EXT = "saml.server.signature.keyinfo.ext";
|
String SAML_SERVER_SIGNATURE_KEYINFO_EXT = "saml.server.signature.keyinfo.ext";
|
||||||
|
String SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER = "saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer";
|
||||||
String SAML_FORCE_POST_BINDING = "saml.force.post.binding";
|
String SAML_FORCE_POST_BINDING = "saml.force.post.binding";
|
||||||
String SAML_ASSERTION_SIGNATURE = "saml.assertion.signature";
|
String SAML_ASSERTION_SIGNATURE = "saml.assertion.signature";
|
||||||
String SAML_ENCRYPT = "saml.encrypt";
|
String SAML_ENCRYPT = "saml.encrypt";
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.keycloak.connections.httpclient.HttpClientProvider;
|
import org.keycloak.connections.httpclient.HttpClientProvider;
|
||||||
import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
import org.keycloak.dom.saml.v2.assertion.AssertionType;
|
||||||
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
|
import org.keycloak.dom.saml.v2.assertion.AttributeStatementType;
|
||||||
|
@ -54,11 +55,13 @@ import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
||||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||||
|
import org.keycloak.saml.common.util.XmlKeyInfoKeyNameTransformer;
|
||||||
import org.keycloak.services.ErrorPage;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.managers.ResourceAdminManager;
|
import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
@ -77,6 +80,7 @@ import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
import org.keycloak.saml.processing.core.util.KeycloakKeySamlExtensionGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,6 +105,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
public static final String SAML_REQUEST_ID = "SAML_REQUEST_ID";
|
public static final String SAML_REQUEST_ID = "SAML_REQUEST_ID";
|
||||||
public static final String SAML_LOGOUT_BINDING = "saml.logout.binding";
|
public static final String SAML_LOGOUT_BINDING = "saml.logout.binding";
|
||||||
public static final String SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO = "saml.logout.addExtensionsElementWithKeyInfo";
|
public static final String SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO = "saml.logout.addExtensionsElementWithKeyInfo";
|
||||||
|
public static final String SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER = "SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER";
|
||||||
public static final String SAML_LOGOUT_REQUEST_ID = "SAML_LOGOUT_REQUEST_ID";
|
public static final String SAML_LOGOUT_REQUEST_ID = "SAML_LOGOUT_REQUEST_ID";
|
||||||
public static final String SAML_LOGOUT_RELAY_STATE = "SAML_LOGOUT_RELAY_STATE";
|
public static final String SAML_LOGOUT_RELAY_STATE = "SAML_LOGOUT_RELAY_STATE";
|
||||||
public static final String SAML_LOGOUT_CANONICALIZATION = "SAML_LOGOUT_CANONICALIZATION";
|
public static final String SAML_LOGOUT_CANONICALIZATION = "SAML_LOGOUT_CANONICALIZATION";
|
||||||
|
@ -379,10 +384,11 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
KeyManager keyManager = session.keys();
|
KeyManager keyManager = session.keys();
|
||||||
KeyManager.ActiveKey keys = keyManager.getActiveKey(realm);
|
KeyManager.ActiveKey keys = keyManager.getActiveKey(realm);
|
||||||
boolean postBinding = isPostBinding(clientSession);
|
boolean postBinding = isPostBinding(clientSession);
|
||||||
|
String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((! postBinding) && samlClient.requiresRealmSignature() && samlClient.addExtensionsElementWithKeyInfo()) {
|
if ((! postBinding) && samlClient.requiresRealmSignature() && samlClient.addExtensionsElementWithKeyInfo()) {
|
||||||
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keys.getKid()));
|
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseType samlModel = builder.buildModel();
|
ResponseType samlModel = builder.buildModel();
|
||||||
|
@ -410,14 +416,14 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
if (canonicalization != null) {
|
if (canonicalization != null) {
|
||||||
bindingBuilder.canonicalizationMethod(canonicalization);
|
bindingBuilder.canonicalizationMethod(canonicalization);
|
||||||
}
|
}
|
||||||
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
||||||
}
|
}
|
||||||
if (samlClient.requiresAssertionSignature()) {
|
if (samlClient.requiresAssertionSignature()) {
|
||||||
String canonicalization = samlClient.getCanonicalizationMethod();
|
String canonicalization = samlClient.getCanonicalizationMethod();
|
||||||
if (canonicalization != null) {
|
if (canonicalization != null) {
|
||||||
bindingBuilder.canonicalizationMethod(canonicalization);
|
bindingBuilder.canonicalizationMethod(canonicalization);
|
||||||
}
|
}
|
||||||
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signAssertions();
|
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signAssertions();
|
||||||
}
|
}
|
||||||
if (samlClient.requiresEncryption()) {
|
if (samlClient.requiresEncryption()) {
|
||||||
PublicKey publicKey = null;
|
PublicKey publicKey = null;
|
||||||
|
@ -513,7 +519,8 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
SAML2LogoutRequestBuilder logoutBuilder = createLogoutRequest(bindingUri, clientSession, client);
|
SAML2LogoutRequestBuilder logoutBuilder = createLogoutRequest(bindingUri, clientSession, client);
|
||||||
if (samlClient.requiresRealmSignature() && samlClient.addExtensionsElementWithKeyInfo()) {
|
if (samlClient.requiresRealmSignature() && samlClient.addExtensionsElementWithKeyInfo()) {
|
||||||
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
||||||
logoutBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keys.getKid()));
|
String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
logoutBuilder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
|
||||||
}
|
}
|
||||||
JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient);
|
JaxrsSAML2BindingBuilder binding = createBindingBuilder(samlClient);
|
||||||
return binding.redirectBinding(logoutBuilder.buildDocument()).request(bindingUri);
|
return binding.redirectBinding(logoutBuilder.buildDocument()).request(bindingUri);
|
||||||
|
@ -555,10 +562,14 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
binding.canonicalizationMethod(canonicalization);
|
binding.canonicalizationMethod(canonicalization);
|
||||||
}
|
}
|
||||||
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
||||||
binding.signatureAlgorithm(algorithm).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
XmlKeyInfoKeyNameTransformer transformer = XmlKeyInfoKeyNameTransformer.from(
|
||||||
|
userSession.getNote(SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER),
|
||||||
|
SamlClient.DEFAULT_XML_KEY_INFO_KEY_NAME_TRANSFORMER);
|
||||||
|
String keyName = transformer.getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
binding.signatureAlgorithm(algorithm).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
||||||
boolean addExtension = (! postBinding) && Objects.equals("true", userSession.getNote(SamlProtocol.SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO));
|
boolean addExtension = (! postBinding) && Objects.equals("true", userSession.getNote(SamlProtocol.SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO));
|
||||||
if (addExtension) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
if (addExtension) { // Only include extension if REDIRECT binding and signing whole SAML protocol message
|
||||||
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keys.getKid()));
|
builder.addExtension(new KeycloakKeySamlExtensionGenerator(keyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +669,8 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder();
|
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder();
|
||||||
if (samlClient.requiresRealmSignature()) {
|
if (samlClient.requiresRealmSignature()) {
|
||||||
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
|
||||||
binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate());
|
||||||
|
binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
|
||||||
}
|
}
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,6 +362,7 @@ public class SamlService extends AuthorizationEndpointBase {
|
||||||
userSession.setNote(SamlProtocol.SAML_LOGOUT_REQUEST_ID, logoutRequest.getID());
|
userSession.setNote(SamlProtocol.SAML_LOGOUT_REQUEST_ID, logoutRequest.getID());
|
||||||
userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding);
|
userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding);
|
||||||
userSession.setNote(SamlProtocol.SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO, Boolean.toString((! postBinding) && samlClient.addExtensionsElementWithKeyInfo()));
|
userSession.setNote(SamlProtocol.SAML_LOGOUT_ADD_EXTENSIONS_ELEMENT_WITH_KEY_INFO, Boolean.toString((! postBinding) && samlClient.addExtensionsElementWithKeyInfo()));
|
||||||
|
userSession.setNote(SamlProtocol.SAML_SERVER_SIGNATURE_KEYINFO_KEY_NAME_TRANSFORMER, samlClient.getXmlSigKeyInfoKeyNameTransformer().name());
|
||||||
userSession.setNote(SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod());
|
userSession.setNote(SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod());
|
||||||
userSession.setNote(AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL);
|
userSession.setNote(AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL);
|
||||||
// remove client from logout requests
|
// remove client from logout requests
|
||||||
|
|
Loading…
Reference in a new issue