在多租户 stup 中使用 Spring Security OAuth 动态注册 OIDC 客户端
Posted
技术标签:
【中文标题】在多租户 stup 中使用 Spring Security OAuth 动态注册 OIDC 客户端【英文标题】:Dynamically register OIDC client with Spring Security OAuth in a multi-tenant stup 【发布时间】:2021-05-31 22:33:21 【问题描述】:我正在构建一个多租户应用程序,它应该允许每个租户使用自己的 IAM 提供程序来进行用户身份验证。最后,例如,Tenant1 可以使用 Keycloak,Tenant2 可以使用 OneIdentity,Tenant3 可以使用它选择的任何 IAM 提供者......应用程序应该能够动态地(在运行时)注册一个新租户及其 IAM 提供者。我注册了具有ClientRegistrationRepository
的 OIDC 客户端,例如:
@Bean
public ClientRegistrationRepository clientRegistrationRepository()
return new InMemoryClientRegistrationRepository(
ClientRegistrations.fromIssuerLocation("iam-provider-1-issuer-location")
.registrationId("registration-id")
.clientId("client-id")
.clientSecret("client-secret")
.build(),
ClientRegistrations.fromIssuerLocation("iam-provider-2-issuer-location")
.registrationId("registration-id")
.clientId("client-id")
.clientSecret("client-secret")
.build(),
);
但是,ClientRegistrationRepository
不提供更新客户端注册的方法。有没有办法在运行时引入新的客户端注册,Spring Security 会考虑到这一点?
【问题讨论】:
看看这些可以在运行时重新加载 bean 的方法:***.com/questions/51218086/… 【参考方案1】:重定向到登录控制器中的 /oauth2/authorization/registrationId。
@GetMapping(path = "/login")
public String defaultLogin(HttpServletRequest request)
String domainName = request.getServerName();
Tenant tenant = tenantService.findByDomainName(domainName);
return String.format("redirect:/oauth2/authorization/%s", tenant.getId());
并覆盖 findByRegistrationId 方法,你可以根据需要更新 ClientRegistration。
@Override
public ClientRegistration findByRegistrationId(String registrationId)
Tenant tenant = tenantService.findById(registrationId);
return ClientRegistration.withRegistrationId(registrationId)
.clientId(tenant.getClientId())
.clientSecret(tenant.getClientSecret())
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUriTemplate("baseUrl/login/oauth2/code/registrationId")
.scope("openid", "profile", "email")
.clientName(registrationId)
.authorizationUri(String.format("https://%s/authorize", tenant.getAuthProviderDomain()))
.tokenUri(String.format("https://%s/oauth/token", tenant.getAuthProviderDomain()))
.userInfoUri(String.format("https://%s/userinfo", tenant.getAuthProviderDomain()))
.jwkSetUri(String.format("https://%s/.well-known/jwks.json", tenant.getAuthProviderDomain()))
.userNameAttributeName("name")
.build();
【讨论】:
以上是关于在多租户 stup 中使用 Spring Security OAuth 动态注册 OIDC 客户端的主要内容,如果未能解决你的问题,请参考以下文章
Spring在多租户环境中为占位符配置application.properties
如何使用 Spring + Hibernate 对实体进行自定义验证以进行多租户设置
在多租户应用程序中如何检查应用程序在 Azure 门户中注册的租户数据?