如何在同一个 Spring Boot 应用程序中使用多个“JWK Set Uri”值?

Posted

技术标签:

【中文标题】如何在同一个 Spring Boot 应用程序中使用多个“JWK Set Uri”值?【英文标题】:How do I use multiple 'JWK Set Uri' values in the same Spring Boot app? 【发布时间】:2020-05-18 18:39:55 【问题描述】:

我需要使用两个不同的授权服务器(两个 Okta 实例)来验证来自单个 Spring Boot 应用程序中两个不同 Web 应用程序的身份验证令牌,该应用程序是一个后端 REST API 层。

目前我有一个资源服务器使用以下配置:

@Configuration
@EnableWebSecurity
public class ResourceServerSecurityConfig extends WebSecurityConfigurerAdapter 

  @Override
  protected void configure(HttpSecurity http) throws Exception
    http
      .authorizeRequests().antMatchers("/public/**").permitAll()
      .anyRequest().authenticated()
      .and()
      .oauth2ResourceServer().jwt();
  

spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-X.okta.com/oauth2/default
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://dev-X.okta.com/oauth2/default/v1/keys

在我的 Spring Boot 应用程序(版本 2.2.4.RELEASE)中具有依赖项 spring-security-oauth2-resource-serverspring-security-oauth2-jose

我想要进入的最终状态是,根据请求中设置的自定义 HTTP 标头,我想选择我的 Spring Boot 应用程序使用哪个 Okta 实例来解码和验证 JWT 令牌。

理想情况下,我的配置文件中有两个属性,如下所示:

jwkSetUri.X=https://dev-X.okta.com/oauth2/default/v1/keys
jwtIssuerUri.X=https://dev-X.okta.com/oauth2/default

jwkSetUri.Y=https://dev-Y.okta.com/oauth2/default/v1/keys
jwtIssuerUri.Y=https://dev-Y.okta.com/oauth2/default

我应该能够使用RequestHeaderRequestMatcher 来匹配安全配置中的标头值。我不能锻炼的是如何使用两个不同的oauth2ResourceServer 实例来配合安全配置。

【问题讨论】:

【参考方案1】:

使用弹簧靴,目前无法开箱即用。 Spring Security 5.3 提供了执行此操作的功能(spring boot 2.2.6 仍然不支持 spring security 5.3)。 请看以下问题:

https://github.com/spring-projects/spring-security/issues/7857https://github.com/spring-projects/spring-security/pull/7887

通过以下我提供的链接,可以手动配置资源服务器以使用多个身份提供者。提供的链接主要用于spring boot webflux开发。有关基本的 Spring Boot Web 开发,请观看此视频:

https://www.youtube.com/watch?v=ke13w8nab-k

【讨论】:

您能否帮助解释一下支持上述 Spring Security 5.3 的 Spring-boot 2.3 是如何实现的? docs.spring.io/spring-security/site/docs/5.3.0.RELEASE/… 访问 url 时只需等待几秒钟,它将直接跳转到具有多个身份提供者的部分。虽然这很容易做到,但您可能仍希望使用手动配置来带来自定义行为(我仍在 spring boot 2.4 中手动配置它)。【参考方案2】:

使用 JwtIssuerAuthenticationManagerResolver 对象从 Spring security 5.3+ 开始,这是可能的

覆盖扩展WebSecurityConfigurerAdapter的配置类中的configure(HttpSecurity http)

JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
            "http://localhost:8080/auth/realms/SpringBootKeyClock",
            "https://accounts.google.com/o/oauth2/auth",
            "https://<subdomain>.okta.com/oauth2/default"
    );

http.cors()
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/user/info", "/api/foos/**")
            .hasAnyAuthority("SCOPE_email")
            .antMatchers(HttpMethod.POST, "/api/foos")
            .hasAuthority("SCOPE_profile")
            .anyRequest()
            .authenticated()
            .and()
            .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));

【讨论】:

这看起来很有用。也有人可以回答这个问题,即在运行时更改弹簧安全配置和在运行时延迟加载安全配置***.com/questions/68831257/… 我知道这是一岁但我想知道如何将上述方式用于多个发行者并在有多个发行者时使用 JwtDecoder jwtDecoder() 验证受众?谢谢 这个答案节省了我的时间,谢谢。

以上是关于如何在同一个 Spring Boot 应用程序中使用多个“JWK Set Uri”值?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot - 日志记录

在 Spring Boot 中读取环境变量

如何在没有spring-boot的情况下使用eureka+feign?

如何在weblogic上运行spring boot

如何在 Spring (Boot) 应用程序的代码中动态添加 bean?

如何在嵌入式 tomcat 服务器上部署 Spring Boot Web 应用程序,来自 Spring Boot 本身