如何使用 System.IdentityModel.Tokens.Jwt 使用 Google OAuth2 兼容算法 RSA SHA-256 生成 JWT?

2023-11-21

我正在尝试创建一个 JWT 以使用服务帐户进行授权,如中所述谷歌文档 using System.IdentityModel.Tokens.Jwt。我有以下代码:

byte[] key = Convert.FromBase64String("...");
var certificate = new X509Certificate2(key, "notasecret");

DateTime now = DateTime.UtcNow;
TimeSpan span = now - UnixEpoch;
Claim[] claims =
{
    new Claim("iss", "[email protected]"),
    new Claim("scope", "https://www.googleapis.com/auth/plus.me"),
    new Claim("aud", "https://accounts.google.com/o/oauth2/token"),
    new Claim("iat", span.TotalSeconds.ToString()),
    new Claim("exp", span.Add(TimeSpan.FromHours(1)).TotalSeconds.ToString())
};

JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var descriptor = new SecurityTokenDescriptor
{
    SigningCredentials = new SigningCredentials(
        new InMemorySymmetricSecurityKey(key),
        "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
        "http://www.w3.org/2001/04/xmlenc#sha256"),
    Subject = new ClaimsIdentity(claims)
};

JwtSecurityToken jwtSecurityToken = (JwtSecurityToken)handler.CreateToken(descriptor);
string json = handler.WriteToken(jwtSecurityToken);

其输出:

{ "typ" : "JWT" , "alg" : "HS256" }

虽然 Google 明确声明支持 SHA-256:

服务帐户依赖于RSA SHA-256算法和 JWT 令牌格式

根据wtSecurityTokenHandler.InboundAlgorithmMap:

RS256 => http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
HS256 => http://www.w3.org/2001/04/xmldsig-more#hmac-sha256 

所以当我更改代码时:

new SigningCredentials(
    new InMemorySymmetricSecurityKey(key),
        "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
        "http://www.w3.org/2001/04/xmlenc#sha256");

我遇到了一个例外:

System.InvalidOperationException: IDX10632: SymmetricSecurityKey.GetKeyedHashAlgorithm( 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) threw an exception.
SymmetricSecurityKey: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey'
SignatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', check to make sure the SignatureAlgorithm is supported.

这是否意味着微软不支持谷歌独家支持的算法?


自从提出这个问题以来已经有一段时间了,但我认为对于未来访问此页面的人来说,可能值得知道的是,使用 .NET Google Auth API 在几行代码中获得相同的结果非常容易(其 nuget 可以在这里找到:Google.Api.Auth

using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;

namespace GoogleTest
{
    public class GoogleOAuth2
    {
        /// <summary>
        /// Authorization scope for our requests
        /// </summary>
        private readonly string _defaultScope;

        /// <summary>
        /// Service account will be of the form [email protected]
        /// </summary>
        private readonly string _serviceAccount;

        /// <summary>
        /// Set this to the full path to your service account private key file.
        /// </summary>
        private readonly string _certificateFile;

        public GoogleOAuth2(string defaultScope, string serviceAccount, string certificateFile)
        {
            _defaultScope = defaultScope;
            _serviceAccount = serviceAccount;
            _certificateFile = certificateFile;
        }

        /// <summary>
        /// Access Token returned by Google Token Server
        /// </summary>
        public string AccessToken { get; set; }

        public async Task<bool> RequestAccessTokenAsync()
        {
            var certificate = new X509Certificate2(_certificateFile, "notasecret", X509KeyStorageFlags.Exportable);
            var serviceAccountCredential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(_serviceAccount)
            {
                Scopes = new[] { _defaultScope }
            }.FromCertificate(certificate));

            var status = await serviceAccountCredential.RequestAccessTokenAsync(CancellationToken.None);
            if (status)
                AccessToken = serviceAccountCredential.Token.AccessToken;
            return status;
        }
    }
}

要获取访问令牌,您只需调用 RequestAccessTokenAsync 方法,如果结果成功,您就会在 AccessToken 属性中获得令牌。

请注意,此实现假设在开发人员控制台中,您已将私钥导出为 .P12 文件。

希望这个答案能有所帮助。

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

如何使用 System.IdentityModel.Tokens.Jwt 使用 Google OAuth2 兼容算法 RSA SHA-256 生成 JWT? 的相关文章

随机推荐

  • Google-api-php 刷新令牌返回 invalid_grant

    我几乎搜索了谷歌第一页的所有结果 但似乎找不到答案 我正在使用 Google API 的刷新令牌并接收 Error refreshing the OAuth2 token message error invalid grant 我在做什么
  • 日期格式转换javascript

    我正在尝试使用 javascript 将 2013 年 7 月 24 日 转换为 DD MM YYYY 但我不断收到错误消息 我在用new Date July 24 2013 format DD MM YYYY 我缺少什么 Date对象没有
  • Python3.4 错误 - 无法启用可执行堆栈,因为共享对象需要:无效参数

    我一直在尝试安装OpenCV在 Windows 上的 Bash Linux 的 Windows 子系统 wsl 环境中 事实证明这非常困难 我想我已经非常接近了 但是进入 python 后 import cv2给出以下错误 ImportEr
  • 在文档 (.docx) 的特定位置添加图像?

    我使用 Python docx 生成 Microsoft Word 文档 用户希望当他写下这样的内容时 大家早上好 这是我的 profile img s 你喜欢吗 在 HTML 字段中 我创建一个 Word 文档 并从数据库中恢复用户的图片
  • 按值对数组进行排序并存储在变量中

    array array 5 4 6 8 5 3 4 6 1 我想排序 array like asort确实如此 但问题是asort是一个函数 它的乘积不能存储在变量中 我怎样才能做这样的事情 array array 5 4 6 8 5 3
  • 如何在 TextView 中的每个单词上使用 onTouchListeners?

    我想将 onTouchListeners 分配给 TextView 中的每个单词 不是链接到互联网上的某些内容 而是为了继续应用程序内的游戏逻辑 此时我的游戏的一般操作是查看 TextView 触摸一个单词 如果它是您获胜的目标单词 否则根
  • 如何从类函数内部访问对象属性[重复]

    这个问题在这里已经有答案了 我的 Javascript 类之一有时需要用 Json 更新 我一直在做一个函数 在给定一个 id 的情况下更新数据数组 但现在我想把它做得更封装 函数更新 在类内部 我做了什么 function File da
  • Angular 2 使用 FormBuilder 访问嵌套 FormArray

    首先 我刚刚从 Angular 2 开始 我正在尝试构建一个嵌套表单并验证它 这是我的 ts 文件的一部分 ngOnInit this myForm this formBuilder group projects this formBuil
  • JavaScript 的正则表达式表示法有什么问题?

    我正在读道格拉斯 克罗克福德的网页 JavaScript 世界上最容易被误解的编程语言 我不禁注意到 在 设计错误 下 他提到了 文字正则表达式的符号 他到底在说什么 JavaScript 的正则表达式表示法有什么问题 为什么 可能与它迫使
  • 将取消引用的智能指针的地址传递给需要原始指针的函数

    假设我正在使用需要使用原始指针的库或框架 使用拥有一些数据的智能指针 然后将取消引用的智能指针的地址传递给需要原始指针的函数 这是有效的做法吗 是的 这是有效的做法 这std智能指针有一个get 成员函数正是为了这个目的 一般来说 当您通过
  • UDF 中的 COLLATE 未按预期工作

    我有一个带有文本字段的表格 我想选择文本全部大写的行 该代码按其应有的方式工作 并返回ABC SELECT txt FROM SELECT ABC AS txt UNION SELECT cdf t WHERE txt COLLATE SQ
  • 只保留字符串中的前 n 个字符?

    JavaScript 有没有办法删除字符串的末尾 我只需要保留字符串的前 8 个字符并删除其余的 const result Hiya how are you substring 0 8 console log result console
  • 在 C++ 中,有什么理由用 for(;condition;) 替换 while(condition) 吗?

    好像 while condition do stuff 完全等价于 for condition do stuff 有什么理由使用后者而不是前者 没有good据我所知原因 您使用不增加任何内容的 for 循环故意误导人们 Update 根据O
  • ASP.NET MVC 4.5.2 连接到 IdentityServer4

    我有一个在 ASP NET MVC 4 5 2 上运行的网站 我有一个 IdentityServer4 服务器正在运行 但是当我尝试对其进行身份验证时 我得到 invalid request 对于 ASP NET Core MVC文档 ha
  • 图像未在 React 中加载

    无法显示图像 出现未找到错误 但我已经提供了它的完整路径 我不知道我哪里错了 class App extends React Component render return div h1 hello h1 img src home priy
  • 我应该在配置文件之外使用 env() 吗?

    我偶然发现了这个https laravel com docs 5 4 configuration configuration caching在文档中 这让我有点困惑 当我想要一个环境变量时 我使用 env 函数返回我想要的内容 根据上面的链
  • postgres 上慢速选择不同查询

    我在一个基本上收集日志信息的表上经常执行以下两个查询 两者都从大量行中选择不同的值 但其中的不同值少于 10 个 我分析了该页面完成的两个 不同 查询 marchena gt explain select distinct auditrec
  • 如何将月份格式化为 mmm 格式?

    我正在尝试使用 VBA 在 Excel 中格式化日期 即当前月份mmm格式 不知何故 我得到的是上个月 而不是当前月份 我查了一下 我的电脑月份是二月 但我得到的是一月 这是我的代码 Cells 1 2 Format month Date
  • 为什么GCC编译的C程序需要.eh_frame部分?

    测试在 32 位 x86 Linux 上进行gcc 4 6 3 使用时gcc编译一个C程序和使用readelf要检查部分信息 我可以看到 eh frame部分和 eh frame hdr里面的部分 例如 这是二进制程序的部分信息Perlbe
  • 如何使用 System.IdentityModel.Tokens.Jwt 使用 Google OAuth2 兼容算法 RSA SHA-256 生成 JWT?

    我正在尝试创建一个 JWT 以使用服务帐户进行授权 如中所述谷歌文档 using System IdentityModel Tokens Jwt 我有以下代码 byte key Convert FromBase64String var ce