.NET/C#调用DocuSign REST API获取信封的认证实现问题
纯C#控制台实现DocuSign JWT认证 + 获取信封文档(无封装类)
前提准备
确保你已安装以下NuGet包:
System.IdentityModel.Tokens.JwtMicrosoft.IdentityModel.TokensSystem.Security.Cryptography
完整代码示例
using System; using System.Net.Http; using System.Text; using System.Security.Cryptography; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; using System.Threading.Tasks; using System.Collections.Generic; namespace DocuSignDirectApiCall { class Program { // 替换为你的实际配置 private const string ClientId = "你的DocuSign Client ID"; private const string ImpersonatedUserId = "要模拟的用户ID"; private const string AccountId = "你的DocuSign账号ID"; private const string EnvelopeId = "目标信封ID"; private const string PrivateKeyPath = "private.key"; // 私钥文件路径 private const string AuthServer = "account-d.docusign.com"; // 开发环境认证地址 private const string RestApiBaseUrl = "https://demo.docusign.net/restapi/v2"; static async Task Main(string[] args) { // 1. 生成JWT并获取访问Token string accessToken = await GetDocuSignAccessTokenAsync(); // 2. 调用API获取信封文档 await GetEnvelopeDocumentAsync(accessToken); } private static async Task<string> GetDocuSignAccessTokenAsync() { // 读取PEM格式私钥 string privateKeyContent = await System.IO.File.ReadAllTextAsync(PrivateKeyPath); RSA rsa = RSA.Create(); rsa.ImportFromPem(privateKeyContent.ToCharArray()); // 构建JWT Token var jwtHandler = new JwtSecurityTokenHandler(); var now = DateTime.UtcNow; var tokenDescriptor = new SecurityTokenDescriptor { Issuer = ClientId, Audience = AuthServer, Expires = now.AddMinutes(1), // JWT有效期不能超过1分钟 Subject = new System.Security.Claims.ClaimsIdentity(new[] { new System.Security.Claims.Claim("sub", ImpersonatedUserId), new System.Security.Claims.Claim("scope", "signature") }), SigningCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256) }; SecurityToken jwtToken = jwtHandler.CreateToken(tokenDescriptor); string jwtAssertion = jwtHandler.WriteToken(jwtToken); // 请求获取访问Token using var httpClient = new HttpClient(); var requestContent = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"), new KeyValuePair<string, string>("assertion", jwtAssertion) }); var response = await httpClient.PostAsync($"https://{AuthServer}/oauth/token", requestContent); response.EnsureSuccessStatusCode(); // 解析返回的Token(简单字符串分割,也可使用Newtonsoft.Json等库解析) string responseJson = await response.Content.ReadAsStringAsync(); return responseJson.Split(new[] { "\"access_token\":\"" }, StringSplitOptions.None)[1].Split('"')[0]; } private static async Task GetEnvelopeDocumentAsync(string accessToken) { using var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}"); // 构建正确的API地址:必须使用AccountId而非ClientId string apiUrl = $"{RestApiBaseUrl}/accounts/{AccountId}/envelopes/{EnvelopeId}/documents/1"; var response = await httpClient.GetAsync(apiUrl); response.EnsureSuccessStatusCode(); // 将文档保存到本地 byte[] documentBytes = await response.Content.ReadAsByteArrayAsync(); await System.IO.File.WriteAllBytesAsync("envelope_document.pdf", documentBytes); Console.WriteLine("文档已成功保存为envelope_document.pdf"); } } }
关键修正说明
- 原生JWT实现:完全手动构建JWT并签名,不依赖任何DocuSign封装类
- API地址修正:原代码误用
ClientId作为账号ID,需替换为DocuSign官方分配的AccountId - 请求格式修正:GET接口不需要附加
StringContent,否则会触发API参数错误 - 私钥处理:使用原生RSA类读取PEM格式私钥,符合DocuSign的认证要求
内容的提问来源于stack exchange,提问作者MoMz
相关产品推荐
相关产品推荐

