You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SpringBoot应用中通过Rest Template直接获取DocuSign JWT Access Token?

解决方案:SpringBoot中直接通过Rest API生成DocuSign JWT Access Token

当然可以直接在应用内通过Rest API调用生成JWT Access Token,你之前走的是授权码流程(需要手动获取code),而JWT认证本身就是为服务端应用设计的无交互授权方式,只需要完成一次初始用户授权后,就能全程在应用内自动获取Token。

必要前提

在开始前,你需要准备好这些信息:

  • 集成密钥(API Key):从DocuSign开发者控制台获取
  • RSA私钥:在DocuSign控制台生成并下载的.pem文件
  • 拟 impersonate 的用户ID:目标用户的DocuSign ID(可从用户详情页获取)
  • DocuSign环境地址:开发环境用account-d.docusign.com,生产环境用account.docusign.com
  • 已完成首次用户授权:用浏览器访问 https://{server}/oauth/auth?response_type=code&scope=signature%20impersonation&client_id={集成密钥}&redirect_uri={你的回调地址},完成授权后这个步骤后续无需重复执行

实现步骤

1. 添加依赖

在build.gradle中添加JWT处理和HTTP请求的依赖:

dependencies {
    // JJWT库用于生成JWT断言
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
    // Spring Web用于RestTemplate
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

2. 生成JWT断言

编写工具方法加载私钥并生成符合DocuSign要求的JWT:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Date;

public class DocusignJwtUtils {
    // 加载RSA私钥
    public static PrivateKey loadPrivateKey(String privateKeyPath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        String key = new String(Files.readAllBytes(Paths.get(privateKeyPath)))
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
                .replaceAll("\\s", "");

        byte[] keyBytes = Base64.getDecoder().decode(key);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

    // 生成JWT断言
    public static String generateJwtAssertion(String apiKey, String userId, String serverUrl, PrivateKey privateKey) {
        long expirationMillis = System.currentTimeMillis() + 3600000; // 1小时过期,DocuSign允许的最长时间
        return Jwts.builder()
                .setIssuer(apiKey)
                .setSubject(userId)
                .setAudience(serverUrl)
                .setExpiration(new Date(expirationMillis))
                .claim("scope", "signature impersonation")
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }
}

3. 用RestTemplate调用Token接口获取Access Token

编写服务类调用DocuSign的OAuth token接口:

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.security.PrivateKey;
import java.util.Map;

@Service
public class DocusignAuthService {
    private final RestTemplate restTemplate;

    public DocusignAuthService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String getJwtAccessToken(String apiKey, String userId, String serverUrl, PrivateKey privateKey) {
        String jwtAssertion = DocusignJwtUtils.generateJwtAssertion(apiKey, userId, serverUrl, privateKey);

        // 构建请求参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
        params.add("assertion", jwtAssertion);

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        String tokenUrl = "https://" + serverUrl + "/oauth/token";

        // 调用接口并解析返回结果
        ResponseEntity<Map> response = restTemplate.postForEntity(tokenUrl, request, Map.class);
        return (String) response.getBody().get("access_token");
    }
}

4. 配置RestTemplate

在SpringBoot配置类中注册RestTemplate:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class AppConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

注意事项

  • 确保私钥文件路径正确,且应用有读取权限
  • JWT的过期时间不能超过1小时,否则会被DocuSign拒绝
  • 首次授权必须完成,否则JWT请求会返回consent_required错误,此时需要引导用户完成授权流程

内容的提问来源于stack exchange,提问作者Sunit Kale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:50:28