使用 Keycloak 和 SpringBoot 的多租户

Posted

技术标签:

【中文标题】使用 Keycloak 和 SpringBoot 的多租户【英文标题】:Multitenancy using Keycloak and SpringBoot 【发布时间】:2018-04-07 07:08:38 【问题描述】:

我正在使用 spring boot 适配器和 keycloak spring boot 适配器来执行多租户,我可以使用 ip 和域名访问页面。 但是当我运行 gradlew 脚本时,似乎没有检测到这个 bean,没有发生任何变化。即使我包含了一个记录器,日志也不会打印,所以我认为这个文件根本没有被读取。我错过了什么吗?或者是否有任何可用于多租户的实现。谢谢。

KeycloakTomcatContextCustomizer

@Component
public class KeycloakTomcatContextCustomizer implements TomcatContextCustomizer

    private static final Logger logger = LoggerFactory.getLogger(KeycloakTomcatContextCustomizerBean.class);

    @Override
    public void customize(Context context)
    
        LoginConfig loginConfig = new LoginConfig();
        loginConfig.setAuthMethod("--KEYCLOAK--");
        context.setLoginConfig(loginConfig);
        context.addSecurityRole("myproject");

        SecurityConstraint constraint = new SecurityConstraint();
        constraint.addAuthRole("myproject");

        SecurityCollection collection = new SecurityCollection();
        collection.addPattern("/contexts");
        constraint.addCollection(collection);

        context.addConstraint(constraint);

        context.addParameter("keycloak.config.resolver", HostBasedKeycloakResolver.class.getName());
    

    public class HostBasedKeycloakResolver extends KeycloakSpringBootConfigResolver
    
        private KeycloakDeployment keycloakDeployment;

        @Autowired
        private AdapterConfig adapterConfig;

        @Override
        public KeycloakDeployment resolve(OIDCHttpFacade.Request request) 
        if (keycloakDeployment != null) 
            return keycloakDeployment;
        

            //get the host part here

        //build keycloakdeployment
            keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfig);
            adapterConfig.setAuthServerUrl("https://"+host+"/auth");
            System.out.println(adapterConfig.getAuthServerUrl());
            return keycloakDeployment;
        
    



我的应用程序.yml\

keycloak:
  cors: true
  realm: Boot-Project
  realmKey: AARjANBgkqhkiYUitdhjnCAQ8AMIIBCgKCAQEArOS/TTjkgjdoiQ7F6m5x206lJ+K9VBpEjkjrignxIdH7pJDWv9UMg2CL1q3Tfkjg/YdjkljgkbsnqrSzjBcIU5HQ2AQLkRm2eCPuLIB23d2VS3hZGqvbyqN42hbk/oRhloS0tS2/frq4fIeU53KQiRPPiBt1IEO7DINoDUXdyOWS7g/rSrMkjjUm9SohXdv8u3aB+mnI8gNwEag17Cj+wqoc1smPj5jb/8Ab3MynQHv4ekgXYFPI5BEQSXXflBLbL2kjqR2xP8y8XTsOz58XLyWBydjN2R37uds9D2TqipU3tdc286b276RhNCwIDAQAB
  auth-server-url: https://$__AUTH_VM__:localhost/auth
  ssl-required: none
  resource: myproject
  bearer-only: true
  public-client: false
  credentials:
    secret: ls5f7c3g-d045-444f-8234-6cth6970726y
  securityConstraints[0]:
    securityCollections[0]:
      name: secured context api and app
      authRoles: 
        - commongui
      patterns:
        - /contexts/*
        - /config.json

【问题讨论】:

【参考方案1】:

我遇到了与您尝试实现的类似情况,您的代码似乎还可以。以下内容可能会对您有所帮助:

1) 来自 keycloak 关于如何实现多租户的官方文档: http://www.keycloak.org/docs/3.2/securing_apps/topics/oidc/java/multi-tenancy.html

从那里,有人指出您需要配置要使用的 KeycloackConfigResolver,但不幸的是,在撰写本文时,我在这张票上找到了在 Spring Boot 中没有方便的方法:

2) Spring Boot 适配器的自定义 KeycloakConfigResolver: https://issues.jboss.org/browse/KEYCLOAK-4139?_sscc=t

3) 在 #1 和 #2 之后,可能发生的情况是 Spring 可能会覆盖您的实现类,具体取决于您的 Spring 配置是如何被解析的。尝试从您正在扩展的类中覆盖更多方法,添加一些日志记录,然后在运行时检查 Spring 日志(如果发生这种情况,您会看到类似“...Overriding bean definition for bean...使用不同的定义:替换...用...")

4) 尝试排除相关类,这样您的实现类就不会被覆盖 例如: @SpringBootApplication(exclude = KeycloakSpringBootConfiguration.class)

希望这有助于或提供一些想法。

问候, 先生。江泽

【讨论】:

为了方便其他可能到达这里的人:这是一个带有 Spring Boot 和 KeyCloak 的多租户示例应用程序(不是由我制作):github.com/vimalKeshu/movie-app跨度> 上面第 2 点提到的 URL 包含了用于 Spring Boot 的 KeycloakConfigResolver 的示例代码。 issues.redhat.com/browse/KEYCLOAK-4139?_sscc=t

以上是关于使用 Keycloak 和 SpringBoot 的多租户的主要内容,如果未能解决你的问题,请参考以下文章

springboot整合keycloak

SpringBoot + Keycloak 适配器设置失败

使用 keycloak 进行 Springboot 测试

springboot 应用程序中的 keycloak.json 文件

Keycloak:将 ldap 组映射到 springboot 角色

如何在 Spring Boot 中将 keycloak 与不同的上下文根和反向代理集成