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

DotNet中UPS API OAuth2认证通用实现及本地测试方法咨询

.NET下实现UPS通用认证逻辑封装的方案

一、创建UPSCommon类库项目

  • 打开Visual Studio,新建**类库(.NET)**项目并命名为UPSCommon,注意选择和四个业务应用匹配的.NET版本(如.NET 6/7/8,保证兼容性)。
  • 类库中添加必要NuGet包:System.Net.Http(用于HTTP请求)、System.Text.Json或Newtonsoft.Json(处理JSON序列化,适配UPS API返回格式)。

二、封装OAuth2认证逻辑

在UPSCommon中创建UPSOAuthClient类,封装认证核心逻辑,自动处理token缓存与过期刷新:

using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace UPSCommon
{
    public class UPSOAuthClient
    {
        private readonly HttpClient _httpClient;
        private readonly string _clientId;
        private readonly string _clientSecret;
        private string _accessToken;
        private DateTime _tokenExpiryTime;

        // 构造函数注入客户端凭据与HttpClient,支持从配置动态传入
        public UPSOAuthClient(HttpClient httpClient, string clientId, string clientSecret)
        {
            _httpClient = httpClient;
            _clientId = clientId;
            _clientSecret = clientSecret;
            // 默认使用UPS沙箱环境地址,生产环境可通过配置切换
            _httpClient.BaseAddress = new Uri("https://wwwcie.ups.com/security/v1/oauth/");
        }

        // 获取有效AccessToken,自动处理缓存与刷新
        public async Task<string> GetValidAccessTokenAsync()
        {
            if (string.IsNullOrEmpty(_accessToken) || DateTime.UtcNow >= _tokenExpiryTime)
            {
                await RefreshAccessTokenAsync();
            }
            return _accessToken;
        }

        // 刷新token核心方法
        private async Task RefreshAccessTokenAsync()
        {
            var authBase64 = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_clientId}:{_clientSecret}"));
            _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authBase64);

            var requestContent = new StringContent("grant_type=client_credentials", Encoding.UTF8, "application/x-www-form-urlencoded");
            var response = await _httpClient.PostAsync("token", requestContent);
            response.EnsureSuccessStatusCode();

            var responseBody = await response.Content.ReadAsStringAsync();
            var tokenResult = JsonSerializer.Deserialize<UPSOAuthToken>(responseBody);

            _accessToken = tokenResult.AccessToken;
            // 提前5分钟过期,避免刚好过期的请求失败
            _tokenExpiryTime = DateTime.UtcNow.AddSeconds(tokenResult.ExpiresIn - 300);
        }
    }

    // 用于反序列化UPS返回的token数据
    internal class UPSOAuthToken
    {
        [JsonPropertyName("access_token")]
        public string AccessToken { get; set; }

        [JsonPropertyName("expires_in")]
        public int ExpiresIn { get; set; }

        [JsonPropertyName("token_type")]
        public string TokenType { get; set; }
    }
}
  • 环境区分:UPS沙箱地址为https://wwwcie.ups.com/security/v1/oauth/,生产地址为https://onlinetools.ups.com/security/v1/oauth/,可通过配置项动态切换。
  • 配置建议:四个业务应用通过各自的appsettings.json存储ClientId、ClientSecret和环境标识,注入到UPSOAuthClient中,避免硬编码。

三、业务应用引用UPSCommon类库

  • 在每个业务应用的项目中,右键依赖项 → 添加项目引用,选中UPSCommon类库。
  • 推荐使用依赖注入管理UPSOAuthClient实例,以ASP.NET Core应用为例,在Program.cs中注册:
// 注册UPSOAuthClient
builder.Services.AddHttpClient<UPSOAuthClient>(client =>
{
    var isSandbox = builder.Configuration.GetValue<bool>("UPS:IsSandbox");
    client.BaseAddress = new Uri(isSandbox ? "https://wwwcie.ups.com/security/v1/oauth/" : "https://onlinetools.ups.com/security/v1/oauth/");
})
.AddTypedClient<UPSOAuthClient>((client, sp) =>
{
    var clientId = builder.Configuration["UPS:ClientId"];
    var clientSecret = builder.Configuration["UPS:ClientSecret"];
    return new UPSOAuthClient(client, clientId, clientSecret);
});
  • 在业务类中注入UPSOAuthClient,调用GetValidAccessTokenAsync()获取token后,再执行原有UPS API请求逻辑,完全不影响原有业务流程。

四、本地Visual Studio测试认证功能

可以直接在本地测试,步骤如下:

  1. 获取UPS沙箱凭据:前往UPS开发者门户注册账号、创建应用,获取沙箱环境的ClientId和ClientSecret。
  2. 配置业务应用:在测试应用(如UPSRating)的appsettings.json中添加配置:
"UPS": {
  "IsSandbox": true,
  "ClientId": "你的沙箱ClientId",
  "ClientSecret": "你的沙箱ClientSecret"
}
  1. 编写测试代码:可在应用的Program.cs中添加临时测试逻辑,或创建控制台应用测试:
var host = Host.CreateDefaultBuilder()
    .ConfigureServices((context, services) =>
    {
        services.AddHttpClient<UPSOAuthClient>(client =>
        {
            client.BaseAddress = new Uri("https://wwwcie.ups.com/security/v1/oauth/");
        })
        .AddTypedClient<UPSOAuthClient>((client, sp) =>
        {
            var clientId = context.Configuration["UPS:ClientId"];
            var clientSecret = context.Configuration["UPS:ClientSecret"];
            return new UPSOAuthClient(client, clientId, clientSecret);
        });
    })
    .Build();

var oauthClient = host.Services.GetRequiredService<UPSOAuthClient>();
var token = await oauthClient.GetValidAccessTokenAsync();
Console.WriteLine($"获取到的AccessToken: {token}");

await host.RunAsync();
  1. 验证结果:启动应用,控制台输出AccessToken即表示认证成功;若报错,检查凭据正确性或网络连通性。还可使用该token调用UPS沙箱API(如Rating接口),验证token有效性。

五、注意事项

  • 分布式缓存:若业务应用为多实例部署,建议将token存储到分布式缓存(如Redis),避免各实例重复请求认证接口。
  • 异常处理:在RefreshAccessTokenAsync中添加异常捕获(如网络异常、UPS返回错误),封装为自定义异常,方便调用方处理。
  • 版本兼容:确保UPSCommon的.NET版本与四个业务应用一致,避免跨版本引用问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:47:08