For this scenario im using Keycloak version 17, which are being installed by using below command.
docker pull quay.io/keycloak/keycloak:17.0.0
And being run by using below command,
docker run -p 8443:8443 -e KC_HOSTNAME=localhost:8443 \
-e KC_HOSTNAME_URL=https://localhost:8443 -e KC_DB=mysql \
-e KC_DB_USERNAME=keycloak -e KC_DB_PASSWORD=password \
-e KC_DB_URL=jdbc:mysql://192.168.56.1:3306/keycloak_db \
quay.io/keycloak/keycloak:17.0.0 start
As for the Spring Boot sourcecode, we are utilizing the same code that are being used in below article,
https://github.com/edwin/spring-boot-and-rhsso
So lets start by setting up our application.properties to pointing to Keycloak’s HTTPS port
keycloak.auth-server-url=https://localhost:8443/
keycloak.realm=external
keycloak.resource=client
keycloak.public-client=false
keycloak.bearer-only=false
keycloak.principal-attribute=preferred_username
keycloak.credentials.secret=xxxxxx
But when HTTPS is created by using a self signed certificate, it will display below error from the Java application console.
o.k.adapters.KeycloakDeployment - Failed to load URLs from https://localhost:8443/realms/external/.well-known/openid-configuration
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:349)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:287)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1340)
... 86 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
... 92 common frames omitted
Thats why we need to include Keycloak’s custom SSL certificate into our Spring Boot application so that Spring Boot able to recognize a self sign certificate.
We can start by using OpenSSL to capture Keycloak’s SSL Certificate
echo "" | openssl s_client -connect localhost:8443 -showcerts 2>/dev/null | openssl x509 -out certfile.cert
It will generate a certificate which is belongs to Keycloak, next step is to create a truststore to contain the corresponding certificate. Below command will create a keystore with the name of “customcacerts” and its password which is “changeit”
keytool -import -alias ca -file certfile.cert \
-keystore customcacerts -storepass changeit
And we can run our Spring Boot application with below command, using the created truststore and its password as parameter.
java -Djavax.net.ssl.trustStore=customcacerts \
-Djavax.net.ssl.trustStorePassword=changeit -jar spring-boot.jar