IssuerSigningKeyResolver 调用异步方法

2024-05-08

我们使用 IssuerSigningKeyResolver,它是 Microsoft.IdentityModel.Tokens 的一部分,用于令牌验证并接受非异步委托。我们调用一个异步方法,这将导致阻塞调用,因此想知道使用它的正确方法是什么。

IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
                {
                    return configurationManager.GetConfigurationAsync().ConfigureAwait(false).GetAwaiter().GetResult().SigningKeys;
                }

我的 asp.net core (3.1) webapi 也遇到了同样的问题,它使用 AWS Cognito 进行身份验证,使用的方法如下所述:

https://medium.com/@marcio_30193/jwt-machine-to-machine-usando-aws-cognito-and-c-b1fab0524712 https://medium.com/@marcio_30193/jwt-machine-to-machine-usando-aws-cognito-and-c-b1fab0524712

这导致了类似于 @Punit 的公共代码块,如下所示;

IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
    // Get JsonWebKeySet from AWS
    var json = new WebClient().DownloadString($"{parameters.ValidIssuer}/.well-known/jwks.json");
    // Deserialize the result
    return JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
}

这段代码的问题在于,在 ASP.NET Core 中,这将导致线程池饥饿。

DownloadString 方法是同步的,但它内部执行 .Result 调用,导致线程阻塞,当请求激增时,这可能会导致线程池饥饿。

我使用 Ben.Blocking 检测器发现了这个阻塞调用 - 非常酷https://github.com/benaadams/Ben.BlockingDetector https://github.com/benaadams/Ben.BlockingDetector https://www.nuget.org/packages/Ben.BlockingDetector/ https://www.nuget.org/packages/Ben.BlockingDetector/

那么如何解决呢?

我尝试过,但我认为在代表内部不可能解决。 IssuerSigningKeyResolver 是同步委托,无法接受异步响应。因此,即使 WebClient 有 DownloadStringAsyncTask,它也会将响应放入 IssuerSigningKeyResolver 不会接受的任务中。

简单的解决方案是跳出框框(或委托)思考。

使用 AWS Cognito,请求的数据位于如下 URL;

https://cognito-idp.{region}.amazonaws.com/{user-pool-id}/.well-known/jwks.json

这将返回 JsonWebKeySet 对象的集合,该对象表示一组加密密钥。

我已与 AWS 确认,该池的数据不应更改,因为当前池上没有密钥轮换策略..所以..

解决方案是在委托方法之外请求此数据并将其传入。

这样做有两个好处;

  1. 它解决了问题
  2. 它更有效率。

这个委托方法在每个请求上执行,因此我们每次都调用这个 .well-known/jwks URL,并且响应(每个环境)永远不会改变!

我的代码如下所示;

    var issuingKeys = GetIssuerSigningKey(AuthSettings.CognitoUserPoolUrl);

        services.AddAuthentication(options => 
            ...
            IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
            {
                return issuingKeys;
            }
            ...
        );
        
    private static IList<JsonWebKey> GetIssuerSigningKey(string cognitioUserPoolUrl)
    {
        var json = new WebClient().DownloadString($"{cognitioUserPoolUrl}/.well-known/jwks.json");
        return JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
    }
            

就我使用 AWS Cognito 的情况而言,这些数据存在更改的风险。 我的解决方案是启动一个带有 30 秒或 60 秒计时器的后台线程,然后在该时间间隔刷新静态 IssueKey。 如果确实发生变化,该网站将出现最多 30 秒的小故障,然后继续。

在 @Punit 的示例中,他从 appSettings 获取 100% 不会更改的签名密钥,因此只需通过获取您的 在设置代码中的委托函数之外签名并返回它。

解决此问题的唯一其他方法是将 IssuerSigningKeyResolver 转换为 IssuerSigningKeyResolverAsync(可能在更高版本的 .Net Core 中)。 (我们目前在 Lambda 中运行代码,目前仅支持 .net 3.1,因此我们尚未尝试更新版本)

希望这可以帮助。

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

IssuerSigningKeyResolver 调用异步方法 的相关文章

  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • C++ 中的双精度型数字

    尽管内部表示有 17 位 但 IEE754 64 位 浮点应该正确表示 15 位有效数字 有没有办法强制第 16 位和第 17 位为零 Ref http msdn microsoft com en us library system dou
  • Unity:通过拦截将两个接口注册为一个单例

    我有一个实现两个接口的类 我想对该类的方法应用拦截 我正在遵循中的建议Unity 将两个接口注册为一个单例 https stackoverflow com questions 1394650 unity register two inter
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 我可以在“字节数”设置为零的情况下调用 memcpy() 和 memmove() 吗?

    当我实际上没有什么可以移动 复制的时候 我是否需要处理这些情况memmove memcpy 作为边缘情况 int numberOfBytes if numberOfBytes 0 memmove dest source numberOfBy
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐