springboot3 keycloak in production

157 Views Asked by At

Recently, we performed upgrades on our Java microservices( to springboot 3.2), leading to significant changes, especially in spring security 6. After analyzing the situation, it became evident that using the same Keycloak URL for both frontend and backend in full HTTP is preferable. This approach ensures consistent JWT signature and eliminates the need for a backend-side certificate (in HTTPS). In the development environment, we successfully addressed this by hardcoding the Keycloak URL for backend APIs (Spring Boot) in the same way as for the frontend.

 security:
  oauth2:
    resourceserver:
       jwt:
        issuer-uri: ${KEYCLOAK_URL}
        jwk-set-uri: ${KEYCLOAK_URL}/protocol/openid-connect/certs

However, challenges arise in the (Staging and Production) environments which is in kubernetes, where the frontend is in HTTPS and the backend is in HTTP within the cluster from svc. In these cases, microservices strictly require the certificate to be installed on the backend side for full HTTPS access; otherwise, errors occur.

The consistency of the Keycloak URL used by both frontend and backend is crucial for ensuring a correct JWT signature and avoiding security issues. The solution successfully implemented in the development environment, where the same Keycloak URL in full HTTP is used for both frontend and backend, is a robust approach. The choice between these options will depend on our specific security needs and infrastructure configuration.

this is the schema in kubernetes

and I get these errors:

org.springframework.security.authentication.AuthenticationServiceException: An error occurred while attempting to decode the Jwt: Couldn't retrieve remote JWK set: org.springframework.web.client.ResourceAccessException: I/O error on GET request for  https://domain -name/auth/realms/myrealm/protocol/openid-connect/certs: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I'm reaching out to you to ensure we follow best practices in security on Kubernetes and to hear your insights on this issue

thank you for your help

1

There are 1 best solutions below

4
ch4mp On

On K8s, both your frontend and Spring resource server should use the publicly exposed service for your authorization server (Keycloak), and this service should be served with SSL (https).

The SSL certificates for your publicly exposed services should be signed by a well known root authority. You could use letsencrypt and cert-manager for that.

As a side note, if your frontend is a SPA (Angular, React, Vue, ...) or a mobile application, it should not be configured as a "public" OAuth2 client (it should not contact the authorization server). Instead, you should probably be using the BFF pattern. I wrote a tutorial for that on Baeldung.