【问题标题】:Spring Security / Keycloak: Securing the same request path with multiple realmsSpring Security / Keycloak:使用多个领域保护相同的请求路径
【发布时间】:2022-08-03 09:21:02
【问题描述】:

我希望两个不同领域的用户(例如人类用户和 S2S 用户)访问同一个休息端点。我能找到的所有多租户示例(例如keycloak multi-tenancy docs)都建议实施KeycloakConfigResolver 以根据请求路径选择单个领域。例如:

public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {
    private final KeycloakDeployment realm1Deployment;
    private final KeycloakDeployment realm2Deployment;

    public PathBasedKeycloakConfigResolver() throws IOException {
        realm1Deployment = buildDeployment(\"realm1.json\");
        realm2Deployment = buildDeployment(\"realm2.json\");
    }

    @Override
    public KeycloakDeployment resolve(HttpFacade.Request request) {
        String path = request.getRelativePath();
        return path.startsWith(\"clients/\") ? realm1Deployment : realm2Deployment;
    }

    private static KeycloakDeployment buildDeployment(String path) throws IOException {
        return KeycloakDeploymentBuilder.build(new ClasspathResource(path).getInputStream());
    }
}

但这需要我为每个请求路径选择一个领域。

我想要不同的功能,我想尝试对多个领域的请求进行身份验证,然后选择第一个成功的。我觉得这将是支持单个 URI 的多个领域的合乎逻辑的方式,但我对实现这一点的建议持开放态度。

    标签: java spring-security keycloak spring-security-oauth2


    【解决方案1】:

    由于 Keycloak 提供了 OAuth2 功能,因此您不一定需要使用 keycloak 适配器(其中很多已被弃用,甚至,请参阅here)。相反,您可以只依赖 Spring Security 的内置功能。

    如何使用多个颁发者为 Spring Security 配置 JWT 身份验证的示例如下所示:

    JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver
        ("https://idp.example.org/issuerOne", "https://idp.example.org/issuerTwo");
    
    http
        .authorizeHttpRequests(authorize -> authorize
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(oauth2 -> oauth2
            .authenticationManagerResolver(authenticationManagerResolver)
        );
    

    在您的情况下,单独的颁发者 URL 将是您各自领域的颁发者 URL。此示例直接取自Spring Security documentation,它还包含有关如何使用 XML 配置实现相同功能的示例,如果您更喜欢使用它。

    当然,从适配器迁移出来,如果你已经在使用它可能并不容易,但由于适配器无论如何都会长期消失,所以尽早评估这样做可能是值得的

    【讨论】:

    • 感谢您的回答。这是一项新服务,因此我不受keycloak-spring-security-adapter 的约束。你能指出任何关于这个被弃用的文档吗?部署 json 文件(例如领域、资源、ssl-required、use-resource-role-mappings、public-client 等)中不仅有颁发者 URL,您能否概述一下我如何将这些传递给颁发者,如果不使用适配器?
    • 这实际上是一项工作。在 $job 中,我们有一个自定义库可以为我们执行此操作,我们可以轻松地在所有 Spring 服务中重用它。例如,我们使用docs.spring.io/spring-security/reference/servlet/oauth2/… 提取领域和客户端角色,docs.spring.io/spring-security/reference/servlet/oauth2/… 提取和验证受众等。这是一项较大的一次性工作,但如果您计划使用多个服务,则值得
    • 感觉您的自定义库与keycloak-spring-security-adapter 的工作类似?所以看起来有适配器很有用
    • @lance-java 看到我的回答,你有链接到 Keycloak adpaters deprecation announcementalternate adapter 支持多租户的属性。
    【解决方案2】:

    Keycloak 适配器已弃用已宣布 there

    你应该看看我写的this OpenID adapter。它开箱即用,可以根据需要与尽可能多的发行者一起使用,并解决了许多 keycloak spring-boot 适配器限制:

    • 与 webmvc (servlets) 和 webflux (reactive) 应用程序兼容
    • spring boot 3 就绪(不扩展 WebSecurityConfigurerAdapter)
    • 不遵守 Keycloak(适用于任何 OpenID 授权服务器)
    • 用于安全单元测试的工具

    基础教程here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2012-09-24
      • 2019-10-13
      • 1970-01-01
      • 2020-05-25
      相关资源
      最近更新 更多