Docusign - "Error":"Invalid_request" 请求 JWT 访问令牌时的响应
Docusign - "Error":"Invalid_request" Response When Requesting JWT Access Token
我正在使用 REST API 并且正在用 C# 实现来自 Docusign 的 Postman Collection 的“02 JWT 访问令牌”。我生成了 RSA 密钥对,header 和 body 已准备好 (Header.Body),采用 Base64 格式。
long d1 = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long d2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 1800;
string header = "{ \"alg\": \"RS256\", \"typ\": \"JWT\"}";
string body = "{ \"iss\": \"" + integrationKey + "\", \"sub\": \"" + apiUsername + "\", \"aud\": \"" + environment + "\", \"iat\": " + d1.ToString() + ", \"exp\": " + d2.ToString() + ", \"scope\": \"signature impersonation\"}";
string base64 = Base64Encode(header) + "." + Base64Encode(body);
Base64编码器:
public string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
我使用了以下代码进行签名,它似乎有效:
private string Sign(string message, string privateKey)
{
try
{
byte[] r = Encoding.UTF8.GetBytes(message);
StringReader strReader = new StringReader(privateKey);
PemReader pemReader = new PemReader(strReader);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
RsaKeyParameters privateRSAKey = (RsaKeyParameters)keyPair.Private;
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
sig.Init(true, privateRSAKey);
sig.BlockUpdate(r, 0, r.Length);
byte[] signedBytes = sig.GenerateSignature();
return Convert.ToBase64String(signedBytes);
}
catch (Exception ex)
{
throw ex;
}
}
然后我提交。断言(下面代码中的标记)的格式为 'Header.Body.Signature':
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://" + environment + "/oauth/token"))
{
var contentList = new List<string>();
contentList.Add($"assertion={token}");
contentList.Add($"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer");
request.Content = new StringContent(string.Join("&", contentList));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", encodedKeys);
HttpResponseMessage response = null;
try
{
using (HttpClient client = new HttpClient())
{
response = await client.SendAsync(request);
}
if (response != null)
return await response.Content.ReadAsStringAsync();
else
throw new Exception();
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
throw ex;
}
}
提交时出现错误,{"error":"Invalid_request"}。
更多信息:
https://developers.docusign.com/platform/auth/jwt/jwt-get-token/
似乎 JWT 断言是从头开始的,这可能会导致许多 problems.DocuSign 建议使用库来进行 JWT 断言。
这个 link 显示了我们的 SDK 的这个过程:
https://github.com/docusign/code-examples-csharp/blob/06c46b235c094be1346e4ddca692aa9b72a82456/launcher-csharp/Common/JWTAuth.cs
对于这种情况,您可能需要尝试一种方法:public static (string, string, string) AuthenticateWithJWT()
。这将使用 .NET Core。
或者您可以使用我们 SDK 上的方法:RequestJWTUserToken。
其中之一可能会解决它,请考虑应该安装和设置 DocuSign 代码示例启动器以使用此方法。
DocuSign OAuth JWT 授权使用具有 RS256
算法的 JWT 令牌。
RS256 是指使用 SHA-256 密钥的 RSA 签名算法。
How to create an RS256 JWT 向您展示如何操作。情况很复杂。我推荐你使用库函数!
对于大多数 DocuSign API 方法,请使用我们 SDK 的 RequestJWTUserToken 方法之一。
问题出在 Base64 编码上。它应该是 Base64Url 编码,格式略有不同。值得庆幸的是,只需添加 '.Replace("=", "").Replace("/", "_").Replace("+", "-");'
public string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes).Replace("=", "").Replace("/", "_").Replace("+", "-");
}
private string Sign(string message, string privateKey)
{
try
{
byte[] r = Encoding.UTF8.GetBytes(message);
StringReader strReader = new StringReader(privateKey);
PemReader pemReader = new PemReader(strReader);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
RsaKeyParameters privateRSAKey = (RsaKeyParameters)keyPair.Private;
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
sig.Init(true, privateRSAKey);
sig.BlockUpdate(r, 0, r.Length);
return Convert.ToBase64String(sig.GenerateSignature()).Replace("=", "").Replace("/", "_").Replace("+", "-");
}
catch (Exception ex)
{
throw ex;
}
}
我正在使用 REST API 并且正在用 C# 实现来自 Docusign 的 Postman Collection 的“02 JWT 访问令牌”。我生成了 RSA 密钥对,header 和 body 已准备好 (Header.Body),采用 Base64 格式。
long d1 = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long d2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 1800;
string header = "{ \"alg\": \"RS256\", \"typ\": \"JWT\"}";
string body = "{ \"iss\": \"" + integrationKey + "\", \"sub\": \"" + apiUsername + "\", \"aud\": \"" + environment + "\", \"iat\": " + d1.ToString() + ", \"exp\": " + d2.ToString() + ", \"scope\": \"signature impersonation\"}";
string base64 = Base64Encode(header) + "." + Base64Encode(body);
Base64编码器:
public string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
我使用了以下代码进行签名,它似乎有效:
private string Sign(string message, string privateKey)
{
try
{
byte[] r = Encoding.UTF8.GetBytes(message);
StringReader strReader = new StringReader(privateKey);
PemReader pemReader = new PemReader(strReader);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
RsaKeyParameters privateRSAKey = (RsaKeyParameters)keyPair.Private;
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
sig.Init(true, privateRSAKey);
sig.BlockUpdate(r, 0, r.Length);
byte[] signedBytes = sig.GenerateSignature();
return Convert.ToBase64String(signedBytes);
}
catch (Exception ex)
{
throw ex;
}
}
然后我提交。断言(下面代码中的标记)的格式为 'Header.Body.Signature':
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://" + environment + "/oauth/token"))
{
var contentList = new List<string>();
contentList.Add($"assertion={token}");
contentList.Add($"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer");
request.Content = new StringContent(string.Join("&", contentList));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", encodedKeys);
HttpResponseMessage response = null;
try
{
using (HttpClient client = new HttpClient())
{
response = await client.SendAsync(request);
}
if (response != null)
return await response.Content.ReadAsStringAsync();
else
throw new Exception();
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
throw ex;
}
}
提交时出现错误,{"error":"Invalid_request"}。
更多信息: https://developers.docusign.com/platform/auth/jwt/jwt-get-token/
似乎 JWT 断言是从头开始的,这可能会导致许多 problems.DocuSign 建议使用库来进行 JWT 断言。 这个 link 显示了我们的 SDK 的这个过程: https://github.com/docusign/code-examples-csharp/blob/06c46b235c094be1346e4ddca692aa9b72a82456/launcher-csharp/Common/JWTAuth.cs
对于这种情况,您可能需要尝试一种方法:public static (string, string, string) AuthenticateWithJWT()
。这将使用 .NET Core。
或者您可以使用我们 SDK 上的方法:RequestJWTUserToken。
其中之一可能会解决它,请考虑应该安装和设置 DocuSign 代码示例启动器以使用此方法。
DocuSign OAuth JWT 授权使用具有 RS256
算法的 JWT 令牌。
RS256 是指使用 SHA-256 密钥的 RSA 签名算法。
How to create an RS256 JWT 向您展示如何操作。情况很复杂。我推荐你使用库函数!
对于大多数 DocuSign API 方法,请使用我们 SDK 的 RequestJWTUserToken 方法之一。
问题出在 Base64 编码上。它应该是 Base64Url 编码,格式略有不同。值得庆幸的是,只需添加 '.Replace("=", "").Replace("/", "_").Replace("+", "-");'
public string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes).Replace("=", "").Replace("/", "_").Replace("+", "-");
}
private string Sign(string message, string privateKey)
{
try
{
byte[] r = Encoding.UTF8.GetBytes(message);
StringReader strReader = new StringReader(privateKey);
PemReader pemReader = new PemReader(strReader);
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
RsaKeyParameters privateRSAKey = (RsaKeyParameters)keyPair.Private;
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
sig.Init(true, privateRSAKey);
sig.BlockUpdate(r, 0, r.Length);
return Convert.ToBase64String(sig.GenerateSignature()).Replace("=", "").Replace("/", "_").Replace("+", "-");
}
catch (Exception ex)
{
throw ex;
}
}