如何在 spring-security 5.2 中增加 RemoteJWKSet 缓存 TTL

2024-01-03

我们使用 spring-security 5.2 通过 JWT 验证来保护我们的 REST API。

随着spring:security:oauth2:resourceserver:jwt:jwk-set-uri属性我们指示远程 JWKS 端点 翻译为 Spring 基于此 URI 创建一个 NimbusJwtDecoder。 再往下,创建一个 RemoteJWKSet 对象,该对象缓存对 JWKS 端点的调用,默认 TTL 为 5 分钟。

有没有办法增加这个 TTL 以最小化远程调用? 也许注入新的DefaultJWKSetCache具有不同 TTL 的实例? 尽可能长时间地将其保留在缓存中似乎是安全的,因为当我们收到带有未知孩子的令牌时,将恢复对 JWKS 端点的调用以更新密钥集。

用于检索密钥的调用堆栈如下

JwtAuthenticationProvider
  public Authentication authenticate(Authentication authentication)
    ...
      jwt = this.jwtDecoder.decode(bearer.getToken())
    ...

o.s.security.oauth2.jwt.NimbusJwtDecoder
    public Jwt decode(String token)
    ...
      Jwt createdJwt = createJwt(token, jwt);
    ...

    private Jwt createJwt(String token, JWT parsedJwt)
    ...
      JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);
    ....

DefaultJWTProcessor
      public JWTClaimsSet process(final JWT jwt, final C context)
        ...
          if (jwt instanceof SignedJWT) {
                return process((SignedJWT)jwt, context);
                }
        ...

      public JWTClaimsSet process(final SignedJWT signedJWT, final C context)
            ...
              List<? extends Key> keyCandidates = selectKeys(signedJWT.getHeader(), claimsSet, context);
          ...

      private List<? extends Key> selectKeys(final JWSHeader header, final JWTClaimsSet claimsSet, final C context)
        ....
          if (getJWSKeySelector() != null) {
                 return getJWSKeySelector().selectJWSKeys(header, context);
                 }      
        ....  


JWSVerificationKeySelector
  public List<Key> selectJWSKeys(final JWSHeader jwsHeader, final C context)
    ...
      List<JWK> jwkMatches = getJWKSource().get(new JWKSelector(jwkMatcher), context);
    ...

RemoteJWKSet
  public List<JWK> get(final JWKSelector jwkSelector, final C context)
  ...
    JWKSet jwkSet = jwkSetCache.get();
        if (jwkSet == null) {
            jwkSet = updateJWKSetFromURL();
        }
  ...


DefaultJWKSetCache  
  public JWKSet get() {

    if (isExpired()) {
      jwkSet = null; // clear
    }

    return jwkSet;
  }

安全依赖:

+- org.springframework.boot:spring-boot-starter-security:jar:2.2.4.RELEASE:compile
|  +- org.springframework.security:spring-security-config:jar:5.2.1.RELEASE:compile
|  \- org.springframework.security:spring-security-web:jar:5.2.1.RELEASE:compile
+- org.springframework.security:spring-security-oauth2-jose:jar:5.2.2.RELEASE:compile
|  +- org.springframework.security:spring-security-core:jar:5.2.1.RELEASE:compile
|  \- org.springframework.security:spring-security-oauth2-core:jar:5.2.1.RELEASE:compile
+- com.nimbusds:nimbus-jose-jwt:jar:8.8:compile
|  +- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
|  \- net.minidev:json-smart:jar:2.3:compile (version selected from constraint [1.3.1,2.3])
|     \- net.minidev:accessors-smart:jar:1.2:compile
|        \- org.ow2.asm:asm:jar:5.0.4:compile
+- org.springframework.security:spring-security-oauth2-resource-server:jar:5.2.1.RELEASE:compile

我最终做了以下事情:

    @Bean
    public JwtDecoder jwtDecoder() {
        JWSKeySelector<SecurityContext> jwsKeySelector = null;
        try {
            URL jwksUrl = new URL("https://localhost/.well-known/openid-configuration/jwks");
            long cacheLifespan = 500;
            long refreshTime = 400;
            JWKSetCache jwkSetCache = new DefaultJWKSetCache(cacheLifespan, refreshTime, TimeUnit.MINUTES);
            RemoteJWKSet<SecurityContext> jwkSet = new RemoteJWKSet<>(jwksUrl,null,jwkSetCache);
            jwsKeySelector = JWSAlgorithmFamilyJWSKeySelector.fromJWKSource(jwkSet);
        }
        catch (KeySourceException e) {
            e.printStackTrace();
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }

        DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
        jwtProcessor.setJWSKeySelector(jwsKeySelector);

        return new NimbusJwtDecoder(jwtProcessor);
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 spring-security 5.2 中增加 RemoteJWKSet 缓存 TTL 的相关文章

随机推荐

  • 在 python 中隐藏或删除 tkinter 的菜单栏

    我可以按照以下说明设置菜单 my tk config menu my menu bar 但是 如何删除或完全隐藏它 my tk config menu None 不起作用 仅供参考 我知道这个问题很旧并且有一个可接受的答案 但这对我在 tk
  • Swing I18N:何时加载属性?

    我正在重构现有的 Java 桌面应用程序 以从 properties 文件加载国际化的 UI 文本标签 在应用程序生命周期中 什么时候是加载属性文件并将字符串填充到内存中的适当时间 现有的实现将每个组件的标签定义为例如 public sta
  • 会员无法使用好友功能

    我收到一个无法解释的错误 这是我的头文件 include
  • python有像C/C++一样的头文件吗? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 python 是否需要像 C C 一样的头文件 包含头文件和导入包有什么区别 不 Python 没有头文件 也没有类似的文件 Java 也没
  • 淘汰赛“如果绑定”不起作用

    使用 Chrome 进行调试时 我可以看到 CoverPrices 有 9 个元素 foreach 循环实际上运行良好 并且表看起来正确 第一个跨度正确绑定到 Item1 但是 if 绑定不起作用并且两个图像都会显示 然而 Item2 中的
  • 在 Django 中重置 SQLite 数据库

    我正在尝试重构 Django 项目 我重命名了几个应用程序并添加了一个新应用程序 并调整了一些模型 我想清除我的数据库和迁移并重新开始 但我不确定如何实现这一点 这就是我所做的 rm r myapp migrations I ran thi
  • Angular 6 Auth0 - 全局未定义

    我已将我的应用程序从 Angular 5 升级到 Angular 6 我现在收到以下错误 Uncaught ReferenceError global is not defined at Object node modules auth0
  • 使用 beeline 时避免在列名中打印表名

    在直线中使用蜂巢时使用简单select查询我想返回表without列名中的表名作为默认值 Example Data 以一个简单的表格为例 教程点 https www tutorialspoint com hive hive create t
  • 使用 PowerShell 的 Stack Overflow 声誉

    如何使用 PowerShell 功能查看我的声誉 您可以使用以下功能 Function Get StackOverFlowReputation param userID client new object System Net WebCli
  • 为什么 `deleteBy` 没有最通用的类​​型有充分的理由吗?

    Haskell 2010 语言报告在第 20 10 1 1 节中指出 deleteBy a gt a gt Bool gt a gt a gt a 事实上 实施中GHC 库 http www haskell org ghc docs lat
  • 设置包含非 ASCII 字符的列的格式

    所以我想对齐包含非 ASCII 字符的字段 以下似乎不起作用 for word1 word2 in hello world 世界 print lt 20 lt 20 format word1 word2 hello world 世界 有解决
  • Codeigniter - 将 2 个文件附加到已从用户表单上传到网络服务器的电子邮件中

    我有一个表格 填写后会上传 2 个文件 一个是 doc docx 或 pdf 另一个是图像文件 我的控制器验证表单正常并将文件上传到服务器 我的问题似乎是访问上传的文件数组 我在表单中引用了名为 uploaded 的变量中的数组 从错误看来
  • 跨源请求被阻止 Microsoft Azure Function

    当尝试从客户端调用远程 Azure 函数时 出现此错误 URL 审查 跨源请求被阻止 同源策略不允许读取远程资源https x x com https x x com 原因 CORS 标头 Access Control Allow Orig
  • Android apk扩展文件libs问题

    我按照开发指南中的步骤来实施 Google Marketplace Play 扩展文件设置 http developer android com guide market expansion files html http develope
  • Jquery 验证插件 - TypeError: $(...).validate 不是函数

    我的脚本抛出错误 类型错误 jQuery validator 未定义additional methods js 20 类型错误 validate 不是函数index php 115 可能是我的 jQuery 代码有错误
  • 在 Jenkins 中使用 OpenJDK 14

    是否可以在 Jenkins Docker 版本 中使用 OpenJDK 14 我通过从此链接解压 JDK 来在配置中设置版本 https download java net openjdk jdk14 ri openjdk 14 36 li
  • rxjs 创建可观察超时总是错误

    好吧 现在我真的很困惑 执行以下代码 const created Rx Observable create observer gt observer next 42 const ofd Rx Observable of 42 const c
  • 具有休眠条件的 COALESCE 函数

    我有一个需要使用的地方COALESCE与休眠标准 有办法实现吗 我正在使用休眠5 0 JPA 规范中有一个用于此目的的 API CriteriaBuilder Coalesce http docs oracle com javaee 6 a
  • 代码分支到底是什么

    什么是代码分支 我在很多地方都看到过它 尤其是有点摆弄 但从未真正考虑过它 它如何减慢程序速度以及编码时我应该考虑什么 我看到提到if声明 我真的不明白这样的代码怎么会减慢代码的速度 如果条件为真 执行以下指令 否则跳转到另一组指令 我看到
  • 如何在 spring-security 5.2 中增加 RemoteJWKSet 缓存 TTL

    我们使用 spring security 5 2 通过 JWT 验证来保护我们的 REST API 随着spring security oauth2 resourceserver jwt jwk set uri属性我们指示远程 JWKS 端