Error when deploying SAML application with the keys in PEM format inside keycloak-saml.xml
closes #32817 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
40049f31fa
commit
125124c2d9
6 changed files with 152 additions and 8 deletions
|
@ -61,6 +61,16 @@
|
|||
<artifactId>keycloak-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk18on</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
|
|
|
@ -26,15 +26,19 @@ import java.security.KeyFactory;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.crypto.CryptoConstants;
|
||||
import org.keycloak.common.util.Base64;
|
||||
import org.keycloak.common.util.BouncyIntegration;
|
||||
import org.keycloak.common.util.PemException;
|
||||
|
||||
/**
|
||||
|
@ -42,6 +46,20 @@ import org.keycloak.common.util.PemException;
|
|||
*/
|
||||
public class PemUtils {
|
||||
|
||||
private static final Logger log = Logger.getLogger(PemUtils.class);
|
||||
|
||||
static {
|
||||
Provider existingBc = Security.getProvider(CryptoConstants.BC_PROVIDER_ID);
|
||||
Provider bcProvider = existingBc == null ? new BouncyCastleProvider() : existingBc;
|
||||
|
||||
if (existingBc == null) {
|
||||
Security.addProvider(bcProvider);
|
||||
log.debugv("Loaded {0} security provider", bcProvider.getClass().getName());
|
||||
} else {
|
||||
log.debugv("Security provider {0} already loaded", bcProvider.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a X509 Certificate from a PEM string
|
||||
*
|
||||
|
@ -124,12 +142,12 @@ public class PemUtils {
|
|||
private static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||
PKCS8EncodedKeySpec spec =
|
||||
new PKCS8EncodedKeySpec(der);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA", CryptoConstants.BC_PROVIDER_ID);
|
||||
return kf.generatePrivate(spec);
|
||||
}
|
||||
|
||||
private static X509Certificate decodeCertificate(InputStream is) throws Exception {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyIntegration.PROVIDER);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", CryptoConstants.BC_PROVIDER_ID);
|
||||
X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
|
||||
is.close();
|
||||
return cert;
|
||||
|
@ -138,7 +156,7 @@ public class PemUtils {
|
|||
private static PublicKey decodePublicKey(byte[] der, String type) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
|
||||
X509EncodedKeySpec spec =
|
||||
new X509EncodedKeySpec(der);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER);
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA", CryptoConstants.BC_PROVIDER_ID);
|
||||
return kf.generatePublic(spec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2024 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.adapters.saml;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
|
||||
import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class DeploymentBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testPropertiesBasedRoleMapper() throws Exception {
|
||||
InputStream is = getClass().getResourceAsStream("config/parsers/keycloak-saml-pem-keys.xml");
|
||||
SamlDeployment deployment = new DeploymentBuilder().build(is, new ResourceLoader() {
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String resource) {
|
||||
return this.getClass().getClassLoader().getResourceAsStream(resource);
|
||||
}
|
||||
});
|
||||
Assert.assertNotNull(deployment);
|
||||
Assert.assertNotNull(deployment.getSigningKeyPair().getPrivate());
|
||||
Assert.assertNotNull(deployment.getSigningKeyPair().getPublic());
|
||||
}
|
||||
}
|
BIN
adapters/saml/core/src/test/resources/keystores/keystore.jks
Executable file
BIN
adapters/saml/core/src/test/resources/keystores/keystore.jks
Executable file
Binary file not shown.
|
@ -0,0 +1,67 @@
|
|||
<!--
|
||||
~ Copyright 2024 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:keycloak:saml:adapter http://www.keycloak.org/schema/keycloak_saml_adapter_1_7.xsd">
|
||||
<SP entityID="http://localhost:8280/employee-sig/"
|
||||
sslPolicy="EXTERNAL"
|
||||
logoutPage="/logout.jsp"
|
||||
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
||||
forceAuthentication="false">
|
||||
<Keys>
|
||||
<Key signing="true" >
|
||||
<PrivateKeyPem>
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC+bNiR4IasHerrZihVxg47K79VL9hJAXmOlVZA36e4M04FYeftmyaY/g3qlH0uM2OaXQAm5FRLWYVnf6HvsF/S5XBT8L+VmC/LF+CxKTEsJDq6RecH/btAr7v/tC5pgNIyOkt0mIfKgp+b+n6eVXCVMn69SWvmAVK/Zsc8z60iHRiLg9b+gRcpo8Uj336gN3NfElzUfBzcroKfU40nXThWsFs96xHSM0myAIa+iGf+c1kEev1784522kFoi2GMM7VHCWyjJUpLp23oqb2FYK/RyDVaAUN43ljQhbNDD7kAygZamXl2KFAI6LIp1HiqfoNZTKcpk4q0FEBooGZz4Xi5AgMBAAECggEAQAE92epp2bhEmdLAg/QKHIFb0jo+rGs+fFpdn3iNWzCDbPO3jPm1Q39BFjPKz5ieReg0gN4GJz1zxZH00CesTaqo0s381z9L8SuZbnK2AGw9ARc1zE3QfrGSsyPQ5c1S2WcWrZ4HJl45X6gWnwmAyeUrDFx9U9XmBkd5eEslmm0wfF782sGPwhVrscZngLZIo9bXmdZTbJtwuh3xtq3nbRWltIK9lLqRniDmYE/DcpxuVDSXfa0+uht/6MQExVohKugKZjUhmXESw+hbWJ6QxDaOyHtNQ35oN5ae2DcZcO5Lj+fURDv/H5ifMi80gWCjVFEsUEaSJJT4kOBdpUutsQKBgQDqkcj/Gctu3Z0Y8plnNR+gzVvo7kcTzPUk4aOIYronAWgrKMXhWbgpB/iP4+zV45BF5oVRK/ngayosPVGOHqFzM/oPHhYQH5b+YEU01DwhA3TpeamNCm3z/wrvvCzM1gvjKoPgQh6yuehYX1k6zI8kKz4RvqTvcPj9OskB/Iu7UwKBgQDP0pgyYcawS/dD1xDldLHorAeruKy5EieR1YEF4GTMUBAjsTHPLlVmYrEfPIeJtbv4AhSXCrPCgdSBJ0Z/sLXWWoq5iVd4G8NQAPEd/pz82mtvN5K63JGih2TXKFtxNdsjoIqyBrXaiSifNXcG0gVxz0/juvKrT0vTxsU7xXaGQwKBgQDnoYZlwkcM93JGTGoHbIIK/D8iSQmPF/mLrfUanMNN+SmwVNbyrPIaMnDVRjF9FPZG0Fgdy9s4LRq8DOEYAk9Tv6PSgdcvnMIx90bf4CRwRUWRuD4htIbXRqa6DYv/ye57KGSJc0F1I/e4LI+kbJN9F+Z3B1c/ysNU7FPJzmT9WQKBgQCBLuVQnBrHx9DiKLPmDg3xFc6G3frv5+sU6eST5JKDtljx9tmBccnAJST4x8VwwrkfRxvJb+uhwtZ3mhRml0/Q+OM2xbrLfGaCOrOm83hebN9PePoKkcUthIAYhoug6dtYYBkW5LjyKURJAxED+lVME5QTeUgTWO1HrU05BFvSxQKBgQDM3mkN40xPcYzp4ZI/DpD/I5ynIM66GbxIDS3WyNBHD249WUR9ybhOIPGXpCFqWmIM9DE5FWJTgxLMdeSAPByCpPlxO5jDiG7S/FWKDDdsi9fdct1AXXg0tQfDHOarThxPTJSWyPFmGghfkwM9/hu/Zzmxr+l7EwaTI6Q2dTKGVQ==
|
||||
</PrivateKeyPem>
|
||||
<CertificatePem>
|
||||
MIIDATCCAemgAwIBAgIIOQ5fb1mWXb4wDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjaHR0cDovL2xvY2FsaG9zdDo4MDgwL2VtcGxveWVlLXNpZy8wIBcNMjQwNjIyMTAwMjI3WhgPMjEyNDA1MjkxMDAyMjdaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmzYkeCGrB3q62YoVcYOOyu/VS/YSQF5jpVWQN+nuDNOBWHn7ZsmmP4N6pR9LjNjml0AJuRUS1mFZ3+h77Bf0uVwU/C/lZgvyxfgsSkxLCQ6ukXnB/27QK+7/7QuaYDSMjpLdJiHyoKfm/p+nlVwlTJ+vUlr5gFSv2bHPM+tIh0Yi4PW/oEXKaPFI99+oDdzXxJc1Hwc3K6Cn1ONJ104VrBbPesR0jNJsgCGvohn/nNZBHr9e/OOdtpBaIthjDO1RwlsoyVKS6dt6Km9hWCv0cg1WgFDeN5Y0IWzQw+5AMoGWpl5dihQCOiyKdR4qn6DWUynKZOKtBRAaKBmc+F4uQIDAQABoyEwHzAdBgNVHQ4EFgQUyPCcw2DKgLMQKLpHfIwjjG+yXsAwDQYJKoZIhvcNAQELBQADggEBAFwjt6JAPc3EQt4S0AjrDlzO6Mt/JuDPaJclrgwjFCQQhdonwpdX3gwSlABGOA337/DZv+lQLeunZlt94ORsBMt2RWWmhVXPF1baBaxpJodyC8k5FHyrNepoNKhqoiSsFiNH3929kN8DCk+SV+z5y55wJ9iIsi9pPYS3yO7kRYZqyZRRtY8iVPoHPCIYsKLGRFBL7iF6QEJx7C9Qml2sOnU5HmMlsDSfrOm+D0BcjBizcqPbt/vdYZlEQT76TCUHWIf+HHXTFquHjORRgb4Z6lFEE+MzO3HgduzM6NncrcS57cLkxirOIDZ5v1bnc/x18VIEy/RupXFRmG9bUCvkcBQ=
|
||||
</CertificatePem>
|
||||
</Key>
|
||||
</Keys>
|
||||
<PrincipalNameMapping policy="FROM_NAME_ID"/>
|
||||
<RoleIdentifiers>
|
||||
<Attribute name="Role"/>
|
||||
</RoleIdentifiers>
|
||||
<IDP entityID="idp">
|
||||
<SingleSignOnService signRequest="true"
|
||||
validateResponseSignature="true"
|
||||
requestBinding="REDIRECT"
|
||||
bindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
|
||||
/>
|
||||
|
||||
<SingleLogoutService
|
||||
validateRequestSignature="true"
|
||||
validateResponseSignature="true"
|
||||
signRequest="true"
|
||||
signResponse="true"
|
||||
requestBinding="REDIRECT"
|
||||
responseBinding="REDIRECT"
|
||||
redirectBindingUrl="http://localhost:8080/auth/realms/demo/protocol/saml"
|
||||
/>
|
||||
<Keys>
|
||||
<Key signing="true">
|
||||
<KeyStore resource="keystores/keystore.jks" password="store123">
|
||||
<Certificate alias="demo"/>
|
||||
</KeyStore>
|
||||
</Key>
|
||||
</Keys>
|
||||
</IDP>
|
||||
</SP>
|
||||
</keycloak-saml-adapter>
|
|
@ -25,10 +25,12 @@
|
|||
forceAuthentication="false">
|
||||
<Keys>
|
||||
<Key signing="true" >
|
||||
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
|
||||
<PrivateKey alias="http://localhost:8080/employee-sig/" password="test123"/>
|
||||
<Certificate alias="http://localhost:8080/employee-sig/"/>
|
||||
</KeyStore>
|
||||
<PrivateKeyPem>
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC+bNiR4IasHerrZihVxg47K79VL9hJAXmOlVZA36e4M04FYeftmyaY/g3qlH0uM2OaXQAm5FRLWYVnf6HvsF/S5XBT8L+VmC/LF+CxKTEsJDq6RecH/btAr7v/tC5pgNIyOkt0mIfKgp+b+n6eVXCVMn69SWvmAVK/Zsc8z60iHRiLg9b+gRcpo8Uj336gN3NfElzUfBzcroKfU40nXThWsFs96xHSM0myAIa+iGf+c1kEev1784522kFoi2GMM7VHCWyjJUpLp23oqb2FYK/RyDVaAUN43ljQhbNDD7kAygZamXl2KFAI6LIp1HiqfoNZTKcpk4q0FEBooGZz4Xi5AgMBAAECggEAQAE92epp2bhEmdLAg/QKHIFb0jo+rGs+fFpdn3iNWzCDbPO3jPm1Q39BFjPKz5ieReg0gN4GJz1zxZH00CesTaqo0s381z9L8SuZbnK2AGw9ARc1zE3QfrGSsyPQ5c1S2WcWrZ4HJl45X6gWnwmAyeUrDFx9U9XmBkd5eEslmm0wfF782sGPwhVrscZngLZIo9bXmdZTbJtwuh3xtq3nbRWltIK9lLqRniDmYE/DcpxuVDSXfa0+uht/6MQExVohKugKZjUhmXESw+hbWJ6QxDaOyHtNQ35oN5ae2DcZcO5Lj+fURDv/H5ifMi80gWCjVFEsUEaSJJT4kOBdpUutsQKBgQDqkcj/Gctu3Z0Y8plnNR+gzVvo7kcTzPUk4aOIYronAWgrKMXhWbgpB/iP4+zV45BF5oVRK/ngayosPVGOHqFzM/oPHhYQH5b+YEU01DwhA3TpeamNCm3z/wrvvCzM1gvjKoPgQh6yuehYX1k6zI8kKz4RvqTvcPj9OskB/Iu7UwKBgQDP0pgyYcawS/dD1xDldLHorAeruKy5EieR1YEF4GTMUBAjsTHPLlVmYrEfPIeJtbv4AhSXCrPCgdSBJ0Z/sLXWWoq5iVd4G8NQAPEd/pz82mtvN5K63JGih2TXKFtxNdsjoIqyBrXaiSifNXcG0gVxz0/juvKrT0vTxsU7xXaGQwKBgQDnoYZlwkcM93JGTGoHbIIK/D8iSQmPF/mLrfUanMNN+SmwVNbyrPIaMnDVRjF9FPZG0Fgdy9s4LRq8DOEYAk9Tv6PSgdcvnMIx90bf4CRwRUWRuD4htIbXRqa6DYv/ye57KGSJc0F1I/e4LI+kbJN9F+Z3B1c/ysNU7FPJzmT9WQKBgQCBLuVQnBrHx9DiKLPmDg3xFc6G3frv5+sU6eST5JKDtljx9tmBccnAJST4x8VwwrkfRxvJb+uhwtZ3mhRml0/Q+OM2xbrLfGaCOrOm83hebN9PePoKkcUthIAYhoug6dtYYBkW5LjyKURJAxED+lVME5QTeUgTWO1HrU05BFvSxQKBgQDM3mkN40xPcYzp4ZI/DpD/I5ynIM66GbxIDS3WyNBHD249WUR9ybhOIPGXpCFqWmIM9DE5FWJTgxLMdeSAPByCpPlxO5jDiG7S/FWKDDdsi9fdct1AXXg0tQfDHOarThxPTJSWyPFmGghfkwM9/hu/Zzmxr+l7EwaTI6Q2dTKGVQ==
|
||||
</PrivateKeyPem>
|
||||
<CertificatePem>
|
||||
MIIDATCCAemgAwIBAgIIOQ5fb1mWXb4wDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjaHR0cDovL2xvY2FsaG9zdDo4MDgwL2VtcGxveWVlLXNpZy8wIBcNMjQwNjIyMTAwMjI3WhgPMjEyNDA1MjkxMDAyMjdaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmzYkeCGrB3q62YoVcYOOyu/VS/YSQF5jpVWQN+nuDNOBWHn7ZsmmP4N6pR9LjNjml0AJuRUS1mFZ3+h77Bf0uVwU/C/lZgvyxfgsSkxLCQ6ukXnB/27QK+7/7QuaYDSMjpLdJiHyoKfm/p+nlVwlTJ+vUlr5gFSv2bHPM+tIh0Yi4PW/oEXKaPFI99+oDdzXxJc1Hwc3K6Cn1ONJ104VrBbPesR0jNJsgCGvohn/nNZBHr9e/OOdtpBaIthjDO1RwlsoyVKS6dt6Km9hWCv0cg1WgFDeN5Y0IWzQw+5AMoGWpl5dihQCOiyKdR4qn6DWUynKZOKtBRAaKBmc+F4uQIDAQABoyEwHzAdBgNVHQ4EFgQUyPCcw2DKgLMQKLpHfIwjjG+yXsAwDQYJKoZIhvcNAQELBQADggEBAFwjt6JAPc3EQt4S0AjrDlzO6Mt/JuDPaJclrgwjFCQQhdonwpdX3gwSlABGOA337/DZv+lQLeunZlt94ORsBMt2RWWmhVXPF1baBaxpJodyC8k5FHyrNepoNKhqoiSsFiNH3929kN8DCk+SV+z5y55wJ9iIsi9pPYS3yO7kRYZqyZRRtY8iVPoHPCIYsKLGRFBL7iF6QEJx7C9Qml2sOnU5HmMlsDSfrOm+D0BcjBizcqPbt/vdYZlEQT76TCUHWIf+HHXTFquHjORRgb4Z6lFEE+MzO3HgduzM6NncrcS57cLkxirOIDZ5v1bnc/x18VIEy/RupXFRmG9bUCvkcBQ=
|
||||
</CertificatePem>
|
||||
</Key>
|
||||
</Keys>
|
||||
<PrincipalNameMapping policy="FROM_NAME_ID"/>
|
||||
|
|
Loading…
Reference in a new issue