0

我正在遵循此处列出的稀疏说明:https ://metamind.readme.io/docs/generate-an-oauth-token-using-your-key

我需要能够生成不记名令牌,以便能够直接从 .net,特别是 .net 4.5 访问 Einstein 服务。

由于对 RSACryptoServiceProvider.ImportRSAPrivateKey 的支持在 .net 5 之前不可用,因此我已将我的 pem 文件(从 salesforce 下载)转换为 xml 格式(使用https://superdry.apphb.com/tools/online-rsa-key -converter),我正在使用它来签署 JWT 断言。我得到一个编码断言,但是当我将它发布到https://api.einstein.ai/v2/oauth2/token服务时,我不断收到“无效令牌”消息。

这是我的代码:

            Claim[] claims = new[] {
                new Claim(JwtRegisteredClaimNames.Sub, this.Username),
                new Claim(JwtRegisteredClaimNames.Aud, this.Endpoint.ToString()),
                new Claim(JwtRegisteredClaimNames.Exp, ((int)expiryUnixTimeStamp).ToString())
            };

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.FromXmlString(this.RsaXmlString);
            RsaSecurityKey rsaSecurityKey = new RsaSecurityKey(provider);
            SigningCredentials signingCredentials = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSha256);

            JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
                new JwtHeader(signingCredentials),
                new JwtPayload(claims)
            );
            
            string jwtToken = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);

我检查了所有参数。我可以使用相同的 pem 密钥和用户名成功创建承载令牌,使用浏览器界面,那么为什么它在代码中失败?

4

1 回答 1

0

这个问题的答案是不要从 Claims 数组中生成一个 JwtPayload。它可以编译,但 Claim 构造函数只接受字符串值。有一个 valueType 参数,但它也是一个字符串,其内容未记录。我找不到 valueType 的值可以让我将“exp”值指定为整数。所以问题是我的 unixtimestamp 被序列化为字符串,这使断言无效。

解决方案: JwtPayload.Add 方法采用对象而不是字符串...

JwtPayload jwtPayload = new JwtPayload();
jwtPayload.Add(JwtRegisteredClaimNames.Sub, this.Username);
jwtPayload.Add(JwtRegisteredClaimNames.Aud, this.Endpoint.ToString());
jwtPayload.Add(JwtRegisteredClaimNames.Exp, (int)expiryUnixTimeStamp);

JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
    new JwtHeader(signingCredentials),
    new JwtPayload(jwtPayload)
);
于 2020-11-12T11:02:23.933 回答