DocuSign JWT访问令牌请求 [英] DocuSign JWT Access Token Request

查看:276
本文介绍了DocuSign JWT访问令牌请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 我正在尝试在沙盒环境中获取访问令牌.
  • 我有一个VB.NET应用程序,并引用了DocuSign.eSign.dll
  • 我检查了docusign C#代码示例,但无法在vb.net中运行它们.

这是我尝试的第一种方法:

This is the first approach I tried:

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) ...

第二种方法使用以下代码:

Second approach was using the following codes:

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

结果与第一个解决方案相同:

This resulted in the same as the first solution:

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

在3rt尝试下,我能够获得结果,但是当我尝试将其作为Postman中请求的断言部分发布时,它返回以下内容:

At my 3rt try I was able to get result however when I try to post this as assertion part of the request in Postman, it returns the following:

{
    "error": "invalid_grant",
    "error_description": "no_valid_keys_or_signatures"
}

我已经花了几个小时来解决这个问题,但是没有运气,谢谢.

I've spent hours to solve the issue but no luck, thanks in advance.

注意:这些都是导入的

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

推荐答案

听起来像您的第三种方法是最好的.特别是因为您的主张不正确.它们应该是:

Sounds like your third approach was best. Especially since your claims were not correct. They should be:

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有用的东西.

I was unable to find anything very useful for creating an RS256 JWT via VB.

这家公司提供收费服务,但我没有经验它.

This company offers something for a fee but I have no experience with it.

Microsoft现在显然可以启用RS256 JWT的创建,但是没有我可以找到的有用示例. 文档.

Microsoft apparently now enables the creation of RS256 JWTs but doesn't have a useful example that I could find. Docs.

请先解决您的问题,然后再提交答案.谢谢!!

我建议打印出软件产生的JWT,然后使用验证工具或过程来验证软件产生的JWT是否达到您的期望.

I suggest printing out the JWT that your software produces, then use a verification tool or procedure to verify that the JWT that your software produces is what you expected.

不幸的是,许多在线验证者只是对声明进行解码.您需要另外检查签名是否正确. (使用DocuSign提供的RSA对中的公钥.)

Unfortunately, many of the online verifiers just decode the claims. You need to additionally check that the signature is correct. (Use the public key from the RSA pair that DocuSign gives you.)

这篇关于DocuSign JWT访问令牌请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆