DocuSign JWT 访问令牌请求
DocuSign JWT Access Token Request
- 我正在尝试在沙盒环境中获取访问令牌。
- 我有一个 VB.NET 应用程序并引用了 DocuSign.eSign.dll
- 我检查了 docusign C# 代码示例,但无法在 vb.net
中找到它们 运行
这是我尝试的第一种方法:
Dim ac As ApiClient = New ApiClient()
Dim privateKeyStream() As Byte = Convert.FromBase64String(PrivateKey)
Dim tokenInfo As OAuth.OAuthToken = ac.RequestJWTUserToken("INTEGRATION_ID", "ACCOUNT_ID", "https://account-d.docusign.com/oauth/token", privateKeyStream, 1)
这导致了以下错误:
System.Exception
HResult=0x80131500
Message=Unexpected PEM type
Source=DocuSign.eSign
StackTrace:
at DocuSign.eSign.Client.ApiClient.CreateRSAKeyFromPem(String key) ...
第二种方法是使用以下代码:
Dim privateKeyStream As Stream = New FileStream("D:\docusign.pem", FileMode.Open)
'Dim privateKeyStream As Stream = New MemoryStream(Encoding.UTF8.GetBytes(PK))
Using SR = New StreamReader(privateKeyStream)
If Not SR Is Nothing And SR.Peek() > 0 Then
Dim privateKeyBytes() As Byte = ReadAsBytes(privateKeyStream)
'Dim privateKeyBytes() As Byte = StreamToByteArray(privateKeyStream)
'Dim privateKeyBytes() As Byte = Convert.FromBase64String(PrivateKey)
'Dim privateKeyBytes() As Byte = Encoding.UTF8.GetBytes(PrivateKey)
Dim privateKeyS As String = Encoding.UTF8.GetString(privateKeyBytes)
Dim handler As JwtSecurityTokenHandler = New JwtSecurityTokenHandler()
handler.SetDefaultTimesOnTokenCreation = False
Dim descriptor As SecurityTokenDescriptor = New SecurityTokenDescriptor()
descriptor.Expires = DateTime.UtcNow.AddHours(1)
descriptor.IssuedAt = DateTime.UtcNow
Dim scopes As List(Of String) = New List(Of String)
scopes.Add(OAuth.Scope_SIGNATURE)
descriptor.Subject = New ClaimsIdentity()
descriptor.Subject.AddClaim(New Claim("scope", String.Join(" ", scopes)))
descriptor.Subject.AddClaim(New Claim("aud", "account-d.docusign.com"))
descriptor.Subject.AddClaim(New Claim("iss", "INTEGRATION_ID"))
descriptor.Subject.AddClaim(New Claim("sub", "ACCOUNT_ID"))
Dim RSA = CreateRSAKeyFromPem(privateKeyS)
Dim rsaKey As RsaSecurityKey = New RsaSecurityKey(RSA)
descriptor.SigningCredentials = New SigningCredentials(rsaKey, SecurityAlgorithms.RsaSha256Signature)
Dim Token = handler.CreateToken(descriptor)
Dim jwtToken As String = handler.WriteToken(Token)
Dim baseUri As String = String.Format("https://{0}/", basePath)
Dim RestClient As RestClient = New RestClient(baseUri)
RestClient.Timeout = 10000
Dim contentType As String = "application/x-www-form-urlencoded"
Dim formParams As New Dictionary(Of String, String)
formParams.Add("grant_type", OAuth.Grant_Type_JWT)
formParams.Add("assertion", jwtToken)
Dim queryParams As New Dictionary(Of String, String)
Dim headerParams As New Dictionary(Of String, String)
headerParams.Add("Content-Type", "application/x-www-form-urlencoded")
headerParams.Add("Cache-Control", "no-store")
headerParams.Add("Pragma", "no-cache")
Dim fileParams As New Dictionary(Of String, FileParameter)
Dim pathParams As New Dictionary(Of String, String)
Dim postBody As Object = Nothing
Dim request As RestRequest = PrepareRequest(basePath, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, pathParams, contentType)
Dim response As IRestResponse = RestClient.Execute(request)
If (response.StatusCode >= HttpStatusCode.OK And response.StatusCode < HttpStatusCode.BadRequest) Then
Dim tokenInfo As OAuth.OAuthToken = JsonConvert.DeserializeObject(Of OAuth.OAuthToken)(response.Content)
Return tokenInfo.access_token
Else
Throw New ApiException(response.StatusCode, "Error while requesting server, received a non successful HTTP code " & response.ResponseStatus & " with response Body: " + response.Content, response.Content)
End If
Else
Throw New ApiException(400, "Private key stream not supplied or is invalid!")
End If
End Using
结果与第一个解决方案相同:
System.Exception
HResult=0x80131500
Message=Unexpected PEM type
Source=PropertyServer
StackTrace:
at PropertyServer.classDocusign.CreateRSAKeyFromPem(String key) in...
我的第三种方法如下:
Dim ar1 As JObject = New JObject()
ar1.Add("typ", "JWT")
ar1.Add("alg", "RS256")
Dim header As String = Base64UrlEncoder.Encode(ar1.ToString)
Dim ar2 As JObject = New JObject()
ar2.Add("iss", "INTEGRATION_ID")
ar2.Add("sub", "ACCOUNT_ID")
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now))
ar2.Add("exp:", DateDiff(DateInterval.Second, New Date(1970, 1, 1), DateAdd(DateInterval.Hour, 1, Now)))
ar2.Add("aud:", "account-d.docusign.com")
ar2.Add("scope", "signature impersonation")
Dim body As String = Base64UrlEncoder.Encode(ar2.ToString)
Dim stringToSign As String = header & "." & body
Dim bytesToSign() As Byte = Encoding.UTF8.GetBytes(stringToSign)
'Dim data() As Byte = Encoding.UTF8.GetBytes(PrivateKey)
'Dim b64 As String = System.Text.Encoding.UTF8.GetString(data)
Dim keyBytes() As Byte = Convert.FromBase64String(PrivateKey)
Dim privKeyObj = Asn1Object.FromByteArray(keyBytes)
Dim privStruct = RsaPrivateKeyStructure.GetInstance(privKeyObj)
Dim sig As ISigner = SignerUtilities.GetSigner("SHA256withRSA")
sig.Init(True, New RsaKeyParameters(True, privStruct.Modulus, privStruct.PrivateExponent))
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length)
Dim signature() As Byte = sig.GenerateSignature()
Dim sign As String = Base64UrlEncoder.Encode(signature)
Return header & "." & body & "." & sign
在我的第 3 次尝试中,我能够得到结果,但是当我尝试 post 将其作为 Postman 请求的断言部分时,它 returns 以下内容:
{
"error": "invalid_grant",
"error_description": "no_valid_keys_or_signatures"
}
我花了几个小时来解决这个问题,但运气不好,提前致谢。
注意:这些是进口的
Imports System.IO
Imports System.Net
Imports System.Text
Imports DocuSign.eSign.Api
Imports DocuSign.eSign.Client
Imports DocuSign.eSign.Client.Auth
Imports DocuSign.eSign.Model
Imports Microsoft.Azure.KeyVault.Cryptography.Algorithms
Imports Newtonsoft.Json.Linq
Imports System.Security.Cryptography
Imports System
Imports System.Collections.Generic
Imports Org.BouncyCastle.Crypto
Imports Org.BouncyCastle.Crypto.Parameters
Imports Org.BouncyCastle.Security
Imports Newtonsoft.Json
Imports Org.BouncyCastle.Asn1
Imports Org.BouncyCastle.Asn1.Pkcs
Imports RestSharp
Imports System.IdentityModel.Tokens.Jwt
Imports Microsoft.IdentityModel.Tokens
Imports System.Security.Claims
Imports Org.BouncyCastle.OpenSsl
Imports System.Security.Cryptography.X509Certificates
听起来你的第三种方法最好。特别是因为您的说法不正确。他们应该是:
ar2.Add("iss", "INTEGRATION_ID")
# sub is NOT the account id
ar2.Add("sub", "GUID_VERSION_OF_USER_ID")
# Check that your date is correct
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now))
# should be exp, not exp:
ar2.Add("exp", DateDiff(DateInterval.Second, New Date(1970, 1, 1),
DateAdd(DateInterval.Hour, 1, Now)))
# should be "aud", not "aud:"
ar2.Add("aud", "account-d.docusign.com")
# only need signature. impersonation is automatically implied.
ar2.Add("scope", "signature")
我找不到任何对通过 VB 创建 RS256 JWT 非常有用的东西。
This company 提供收费的东西,但我没有使用过。
Microsoft 显然现在可以创建 RS256 JWT,但没有我能找到的有用示例。 Docs.
一旦您弄明白了,请提交您自己问题的答案。谢谢!!
已添加
我建议打印出你的软件产生的 JWT,然后使用验证工具或程序验证你的软件产生的 JWT 是否符合你的预期。
不幸的是,许多在线验证者只是解码声明。您还需要检查签名是否正确。 (使用 DocuSign 为您提供的 RSA 对中的 public 密钥。)
在 Larry K 的帮助下终于搞定了!
我不确定在 Larry 昨天的回复后我又错过了什么,但我现在可以使用以下代码获得访问令牌:(顺便说一句,将 iat 和 exp 设置为 UTC 或当地时间没有区别)
...Addinionally 私钥声明如下:
Dim PrivateKey As String = "MIIEowIBAAKCAQEAjtTe7UUP/CBI9s...BLABLABLA...JfwZ2hHqFPXA9ecbhc0".Replace(vbLf, "").Replace(vbCr, "")
Dim ar1 As JObject = New JObject()
ar1.Add("typ", "JWT")
ar1.Add("alg", "RS256")
Dim header As String = Base64UrlEncoder.Encode(ar1.ToString)
Dim ar2 As JObject = New JObject()
ar2.Add("iss", "INTEGRATION_ID")
ar2.Add("sub", "GUID_VERSION_OF_USER_ID")
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now().ToUniversalTime))
ar2.Add("exp", DateDiff(DateInterval.Second, New Date(1970, 1, 1), DateAdd(DateInterval.Hour, 1, Now().ToUniversalTime)))
ar2.Add("aud", "account-d.docusign.com")
ar2.Add("scope", "signature")
Dim body As String = Base64UrlEncoder.Encode(ar2.ToString)
Dim stringToSign As String = header & "." & body
Dim bytesToSign() As Byte = Encoding.UTF8.GetBytes(stringToSign)
Dim keyBytes() As Byte = Convert.FromBase64String(PrivateKey)
Dim privKeyObj = Asn1Object.FromByteArray(keyBytes)
Dim privStruct = RsaPrivateKeyStructure.GetInstance(privKeyObj)
Dim sig As ISigner = SignerUtilities.GetSigner("SHA256withRSA")
sig.Init(True, New RsaKeyParameters(True, privStruct.Modulus, privStruct.PrivateExponent))
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length)
Dim signature() As Byte = sig.GenerateSignature()
Dim sign As String = Base64UrlEncoder.Encode(signature)
Return header & "." & body & "." & sign
非常感谢 Larry K!
- 我正在尝试在沙盒环境中获取访问令牌。
- 我有一个 VB.NET 应用程序并引用了 DocuSign.eSign.dll
- 我检查了 docusign C# 代码示例,但无法在 vb.net 中找到它们 运行
这是我尝试的第一种方法:
Dim ac As ApiClient = New ApiClient()
Dim privateKeyStream() As Byte = Convert.FromBase64String(PrivateKey)
Dim tokenInfo As OAuth.OAuthToken = ac.RequestJWTUserToken("INTEGRATION_ID", "ACCOUNT_ID", "https://account-d.docusign.com/oauth/token", privateKeyStream, 1)
这导致了以下错误:
System.Exception
HResult=0x80131500
Message=Unexpected PEM type
Source=DocuSign.eSign
StackTrace:
at DocuSign.eSign.Client.ApiClient.CreateRSAKeyFromPem(String key) ...
第二种方法是使用以下代码:
Dim privateKeyStream As Stream = New FileStream("D:\docusign.pem", FileMode.Open)
'Dim privateKeyStream As Stream = New MemoryStream(Encoding.UTF8.GetBytes(PK))
Using SR = New StreamReader(privateKeyStream)
If Not SR Is Nothing And SR.Peek() > 0 Then
Dim privateKeyBytes() As Byte = ReadAsBytes(privateKeyStream)
'Dim privateKeyBytes() As Byte = StreamToByteArray(privateKeyStream)
'Dim privateKeyBytes() As Byte = Convert.FromBase64String(PrivateKey)
'Dim privateKeyBytes() As Byte = Encoding.UTF8.GetBytes(PrivateKey)
Dim privateKeyS As String = Encoding.UTF8.GetString(privateKeyBytes)
Dim handler As JwtSecurityTokenHandler = New JwtSecurityTokenHandler()
handler.SetDefaultTimesOnTokenCreation = False
Dim descriptor As SecurityTokenDescriptor = New SecurityTokenDescriptor()
descriptor.Expires = DateTime.UtcNow.AddHours(1)
descriptor.IssuedAt = DateTime.UtcNow
Dim scopes As List(Of String) = New List(Of String)
scopes.Add(OAuth.Scope_SIGNATURE)
descriptor.Subject = New ClaimsIdentity()
descriptor.Subject.AddClaim(New Claim("scope", String.Join(" ", scopes)))
descriptor.Subject.AddClaim(New Claim("aud", "account-d.docusign.com"))
descriptor.Subject.AddClaim(New Claim("iss", "INTEGRATION_ID"))
descriptor.Subject.AddClaim(New Claim("sub", "ACCOUNT_ID"))
Dim RSA = CreateRSAKeyFromPem(privateKeyS)
Dim rsaKey As RsaSecurityKey = New RsaSecurityKey(RSA)
descriptor.SigningCredentials = New SigningCredentials(rsaKey, SecurityAlgorithms.RsaSha256Signature)
Dim Token = handler.CreateToken(descriptor)
Dim jwtToken As String = handler.WriteToken(Token)
Dim baseUri As String = String.Format("https://{0}/", basePath)
Dim RestClient As RestClient = New RestClient(baseUri)
RestClient.Timeout = 10000
Dim contentType As String = "application/x-www-form-urlencoded"
Dim formParams As New Dictionary(Of String, String)
formParams.Add("grant_type", OAuth.Grant_Type_JWT)
formParams.Add("assertion", jwtToken)
Dim queryParams As New Dictionary(Of String, String)
Dim headerParams As New Dictionary(Of String, String)
headerParams.Add("Content-Type", "application/x-www-form-urlencoded")
headerParams.Add("Cache-Control", "no-store")
headerParams.Add("Pragma", "no-cache")
Dim fileParams As New Dictionary(Of String, FileParameter)
Dim pathParams As New Dictionary(Of String, String)
Dim postBody As Object = Nothing
Dim request As RestRequest = PrepareRequest(basePath, Method.POST, queryParams, postBody, headerParams, formParams, fileParams, pathParams, contentType)
Dim response As IRestResponse = RestClient.Execute(request)
If (response.StatusCode >= HttpStatusCode.OK And response.StatusCode < HttpStatusCode.BadRequest) Then
Dim tokenInfo As OAuth.OAuthToken = JsonConvert.DeserializeObject(Of OAuth.OAuthToken)(response.Content)
Return tokenInfo.access_token
Else
Throw New ApiException(response.StatusCode, "Error while requesting server, received a non successful HTTP code " & response.ResponseStatus & " with response Body: " + response.Content, response.Content)
End If
Else
Throw New ApiException(400, "Private key stream not supplied or is invalid!")
End If
End Using
结果与第一个解决方案相同:
System.Exception
HResult=0x80131500
Message=Unexpected PEM type
Source=PropertyServer
StackTrace:
at PropertyServer.classDocusign.CreateRSAKeyFromPem(String key) in...
我的第三种方法如下:
Dim ar1 As JObject = New JObject()
ar1.Add("typ", "JWT")
ar1.Add("alg", "RS256")
Dim header As String = Base64UrlEncoder.Encode(ar1.ToString)
Dim ar2 As JObject = New JObject()
ar2.Add("iss", "INTEGRATION_ID")
ar2.Add("sub", "ACCOUNT_ID")
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now))
ar2.Add("exp:", DateDiff(DateInterval.Second, New Date(1970, 1, 1), DateAdd(DateInterval.Hour, 1, Now)))
ar2.Add("aud:", "account-d.docusign.com")
ar2.Add("scope", "signature impersonation")
Dim body As String = Base64UrlEncoder.Encode(ar2.ToString)
Dim stringToSign As String = header & "." & body
Dim bytesToSign() As Byte = Encoding.UTF8.GetBytes(stringToSign)
'Dim data() As Byte = Encoding.UTF8.GetBytes(PrivateKey)
'Dim b64 As String = System.Text.Encoding.UTF8.GetString(data)
Dim keyBytes() As Byte = Convert.FromBase64String(PrivateKey)
Dim privKeyObj = Asn1Object.FromByteArray(keyBytes)
Dim privStruct = RsaPrivateKeyStructure.GetInstance(privKeyObj)
Dim sig As ISigner = SignerUtilities.GetSigner("SHA256withRSA")
sig.Init(True, New RsaKeyParameters(True, privStruct.Modulus, privStruct.PrivateExponent))
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length)
Dim signature() As Byte = sig.GenerateSignature()
Dim sign As String = Base64UrlEncoder.Encode(signature)
Return header & "." & body & "." & sign
在我的第 3 次尝试中,我能够得到结果,但是当我尝试 post 将其作为 Postman 请求的断言部分时,它 returns 以下内容:
{
"error": "invalid_grant",
"error_description": "no_valid_keys_or_signatures"
}
我花了几个小时来解决这个问题,但运气不好,提前致谢。
注意:这些是进口的
Imports System.IO
Imports System.Net
Imports System.Text
Imports DocuSign.eSign.Api
Imports DocuSign.eSign.Client
Imports DocuSign.eSign.Client.Auth
Imports DocuSign.eSign.Model
Imports Microsoft.Azure.KeyVault.Cryptography.Algorithms
Imports Newtonsoft.Json.Linq
Imports System.Security.Cryptography
Imports System
Imports System.Collections.Generic
Imports Org.BouncyCastle.Crypto
Imports Org.BouncyCastle.Crypto.Parameters
Imports Org.BouncyCastle.Security
Imports Newtonsoft.Json
Imports Org.BouncyCastle.Asn1
Imports Org.BouncyCastle.Asn1.Pkcs
Imports RestSharp
Imports System.IdentityModel.Tokens.Jwt
Imports Microsoft.IdentityModel.Tokens
Imports System.Security.Claims
Imports Org.BouncyCastle.OpenSsl
Imports System.Security.Cryptography.X509Certificates
听起来你的第三种方法最好。特别是因为您的说法不正确。他们应该是:
ar2.Add("iss", "INTEGRATION_ID")
# sub is NOT the account id
ar2.Add("sub", "GUID_VERSION_OF_USER_ID")
# Check that your date is correct
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now))
# should be exp, not exp:
ar2.Add("exp", DateDiff(DateInterval.Second, New Date(1970, 1, 1),
DateAdd(DateInterval.Hour, 1, Now)))
# should be "aud", not "aud:"
ar2.Add("aud", "account-d.docusign.com")
# only need signature. impersonation is automatically implied.
ar2.Add("scope", "signature")
我找不到任何对通过 VB 创建 RS256 JWT 非常有用的东西。
This company 提供收费的东西,但我没有使用过。
Microsoft 显然现在可以创建 RS256 JWT,但没有我能找到的有用示例。 Docs.
一旦您弄明白了,请提交您自己问题的答案。谢谢!!
已添加
我建议打印出你的软件产生的 JWT,然后使用验证工具或程序验证你的软件产生的 JWT 是否符合你的预期。
不幸的是,许多在线验证者只是解码声明。您还需要检查签名是否正确。 (使用 DocuSign 为您提供的 RSA 对中的 public 密钥。)
在 Larry K 的帮助下终于搞定了! 我不确定在 Larry 昨天的回复后我又错过了什么,但我现在可以使用以下代码获得访问令牌:(顺便说一句,将 iat 和 exp 设置为 UTC 或当地时间没有区别)
...Addinionally 私钥声明如下:
Dim PrivateKey As String = "MIIEowIBAAKCAQEAjtTe7UUP/CBI9s...BLABLABLA...JfwZ2hHqFPXA9ecbhc0".Replace(vbLf, "").Replace(vbCr, "")
Dim ar1 As JObject = New JObject()
ar1.Add("typ", "JWT")
ar1.Add("alg", "RS256")
Dim header As String = Base64UrlEncoder.Encode(ar1.ToString)
Dim ar2 As JObject = New JObject()
ar2.Add("iss", "INTEGRATION_ID")
ar2.Add("sub", "GUID_VERSION_OF_USER_ID")
ar2.Add("iat", DateDiff(DateInterval.Second, New Date(1970, 1, 1), Now().ToUniversalTime))
ar2.Add("exp", DateDiff(DateInterval.Second, New Date(1970, 1, 1), DateAdd(DateInterval.Hour, 1, Now().ToUniversalTime)))
ar2.Add("aud", "account-d.docusign.com")
ar2.Add("scope", "signature")
Dim body As String = Base64UrlEncoder.Encode(ar2.ToString)
Dim stringToSign As String = header & "." & body
Dim bytesToSign() As Byte = Encoding.UTF8.GetBytes(stringToSign)
Dim keyBytes() As Byte = Convert.FromBase64String(PrivateKey)
Dim privKeyObj = Asn1Object.FromByteArray(keyBytes)
Dim privStruct = RsaPrivateKeyStructure.GetInstance(privKeyObj)
Dim sig As ISigner = SignerUtilities.GetSigner("SHA256withRSA")
sig.Init(True, New RsaKeyParameters(True, privStruct.Modulus, privStruct.PrivateExponent))
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length)
Dim signature() As Byte = sig.GenerateSignature()
Dim sign As String = Base64UrlEncoder.Encode(signature)
Return header & "." & body & "." & sign
非常感谢 Larry K!