最近,我们对 Java 微服务进行了升级(到 springboot 3.2),导致了重大变化,特别是在 Spring Security 6 中。分析情况后,很明显,在完整的 HTTP 中为前端和后端使用相同的 Keycloak URL 是更可取。 此方法可确保一致的 JWT 签名,并消除对后端证书(在 HTTPS 中)的需要。在开发环境中,我们通过与前端相同的方式对后端 API (Spring Boot) 的 Keycloak URL 进行硬编码,成功解决了这个问题。
security:
oauth2:
resourceserver:
jwt:
issuer-uri: ${KEYCLOAK_URL}
jwk-set-uri: ${KEYCLOAK_URL}/protocol/openid-connect/certs
但是,在 kubernetes 中的(登台和生产)环境中出现了挑战,其中前端采用 HTTPS,后端采用来自 svc 的集群内的 HTTP。在这些情况下,微服务严格要求在后端安装证书才能进行完整的 HTTPS 访问;否则会出现错误。
前端和后端使用的Keycloak URL的一致性对于确保正确的JWT签名和避免安全问题至关重要。该解决方案在开发环境中成功实施,前端和后端使用完整 HTTP 中的相同 Keycloak URL,这是一种稳健的方法。这些选项之间的选择将取决于我们特定的安全需求和基础设施配置。
我收到这些错误:
org.springframework.security.authentication.AuthenticationServiceException:尝试解码 Jwt 时发生错误:无法检索远程 JWK 集:org.springframework.web.client.ResourceAccessException:https:// 的 GET 请求上出现 I/O 错误/domain -name/auth/realms/myrealm/protocol/openid-connect/certs:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径
我正在与您联系,以确保我们遵循 Kubernetes 安全性的最佳实践,并听取您对此问题的见解
谢谢您的帮助
在 K8s 上,您的前端和 Spring 资源服务器都应使用公开的授权服务器服务(Keycloak),并且该服务应使用 SSL (https) 提供服务。
公开服务的 SSL 证书应由知名根机构签名。您可以使用 letsencrypt 和 cert-manager 来实现。
顺便说一句,如果您的前端是 SPA(Angular、React、Vue,...)或移动应用程序,不应该将其配置为“公共”OAuth2 客户端(它不应该联系授权服务器) )。相反,您可能应该使用 BFF 模式。我为此写了一个教程。