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测试认证功能
可以直接在本地测试,步骤如下:
- 获取UPS沙箱凭据:前往UPS开发者门户注册账号、创建应用,获取沙箱环境的ClientId和ClientSecret。
- 配置业务应用:在测试应用(如UPSRating)的
appsettings.json中添加配置:
"UPS": { "IsSandbox": true, "ClientId": "你的沙箱ClientId", "ClientSecret": "你的沙箱ClientSecret" }
- 编写测试代码:可在应用的
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();
- 验证结果:启动应用,控制台输出AccessToken即表示认证成功;若报错,检查凭据正确性或网络连通性。还可使用该token调用UPS沙箱API(如Rating接口),验证token有效性。
五、注意事项
- 分布式缓存:若业务应用为多实例部署,建议将token存储到分布式缓存(如Redis),避免各实例重复请求认证接口。
- 异常处理:在
RefreshAccessTokenAsync中添加异常捕获(如网络异常、UPS返回错误),封装为自定义异常,方便调用方处理。 - 版本兼容:确保UPSCommon的.NET版本与四个业务应用一致,避免跨版本引用问题。
内容的提问来源于stack exchange,提问作者Explorer
相关产品推荐
相关产品推荐

