【问题标题】:Spring Security 5.3 Resource Server Multiple KeysSpring Security 5.3 资源服务器多键
【发布时间】:2020-11-13 10:19:38
【问题描述】:

我们有以下场景:

  1. 多个“旧版”Spring Security Oauth2 身份验证服务器 (2.3.4) - 每个都配置了不同的 RSA 密钥,用于创建 JWT 令牌。
  2. 单个较新的(SS 5.3.3、SB 2.3.1)资源服务器,我们要接受来自任一身份验证服务器的令牌。

问题是资源服务器仅配置了 1 个密钥(当前)-因此它只能接受来自 1 个身份验证服务器的令牌。
是否有任何可以想象的方法来支持我们的资源服务器中的多个密钥来解码来自不同身份验证服务器的 JWT?

我们基本上想这样做,但有多个键: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver-jwt-decoder-public-key

Spring Security 5.3 表明这可以通过“多租户”https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2resourceserver-multitenancy 实现

这是一个基本配置

    @Value("${security.oauth2.resourceserver.jwt.key-value}")
    RSAPublicKey key;


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http

                // using new Spring Security SpE"{{LOCATOR_BASE_URL}}"L
                //https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#webflux-oauth2resourceserver-jwt-authorization
                .authorizeRequests(authorizeRequests ->
                                authorizeRequests

                                        .antMatchers("/shipments/**").hasAuthority("SCOPE_DOMPick")
                                                                               .anyRequest().authenticated()
                )

                .csrf().disable()

                // ****** this is the new DSL way in Spring Security 5.2 instead of Spring Security Oauth @EnableResourceServer ******
                .oauth2ResourceServer(oauth2ResourceServer ->
                        oauth2ResourceServer
                                .jwt(jwt ->
                                        jwt.decoder(jwtDecoder())
                                )
                );

    }

    // static key
    @Bean
    JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withPublicKey(this.key).build();

【问题讨论】:

    标签: spring spring-boot spring-security jwt spring-security-oauth2


    【解决方案1】:

    是的,Spring Security 5.3 允许您使用多个 jwk-uri 密钥。请在此处阅读我的答案:

    https://stackoverflow.com/a/61615389/12053054

    如果您不能使用此版本的 SS,可以手动配置 spring security 以使用多个 jwk-uri 密钥。 (按照我提供的链接查看方法)。

    Spring Security 文档的这一部分指定了如何使用 Spring Security 5.3 执行此操作: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver-multitenancy

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

    请注意,颁发者 url 是从传入令牌解析的(JWT oauth2 令牌始终包含颁发者 url,其中可以找到 jwk 的 uri 以验证 JWT 令牌)。通过手动配置(我已发布的答案),您可以添加自定义行为,例如:您可以检查标头以获取解析哪个颁发者 URL 的信息,而不是直接从 JWT 查找应该使用哪个 ulr 来验证令牌(您已经在 spring 中指定了它们) app) 应与此请求一起用于验证 JWT 令牌。

    【讨论】:

    • 谢谢我已经看过这篇文章 - 问题是我们没有用于任何身份验证服务器的 JWK uris。我们严格使用预定义的密钥,这些密钥从 auth-server 手动共享到每个资源服务器。可以改造现有的身份验证服务器以公开 jks 端点,但希望尽可能避免这种情况。
    • 您仍然可以使用此功能。我提到的最后一个链接显示了如何手动配置身份验证。通过手动配置,您可以设置应如何验证令牌。例如,您可以通过标头 (jwk-key: key-1 | key-2) 中提供的值来解析应该使用哪个密钥,然后根据此值,您可以通过存储的 JWK 验证令牌。负责此配置的类称为JwtIssuerAuthenticationManagerResolver,您可以查看它的实现并实现它并自己使用它,如代码帖子中所示。更好的方法是公开 JWK 密钥
    猜你喜欢
    • 2013-12-21
    • 2017-02-13
    • 2019-11-27
    • 2016-01-08
    • 2022-11-19
    • 2018-07-08
    • 2017-03-25
    • 2018-08-17
    • 2017-12-15
    相关资源
    最近更新 更多