如何在.NET通用主机中注册OpenAPI生成的OAuth2 TokenProvider?
依赖注入注册TokenProvider示例
1. 配置文件参数(appsettings.json)
先在配置文件中添加OAuth2相关参数:
{ "OAuth": { "ClientId": "your-client-id", "ClientSecret": "your-client-secret", "TokenEndpoint": "https://your-auth-server/oauth2/token" }, "ApiBaseUrl": "https://your-api-base-url/" }
2. 配置绑定类
创建类映射OAuth配置项:
public class OAuthClientOptions { public string ClientId { get; set; } = string.Empty; public string ClientSecret { get; set; } = string.Empty; public string TokenEndpoint { get; set; } = string.Empty; }
3. 核心注册代码
在Generic Host的Program.cs中完成依赖注入配置:
var builder = Host.CreateDefaultBuilder(args); builder.ConfigureServices((context, services) => { // 绑定OAuth配置到实体类 services.Configure<OAuthClientOptions>(context.Configuration.GetSection("OAuth")); // 注册TokenProvider实现(需实现生成代码中的TokenProvider<OAuthToken>接口) services.AddSingleton<TokenProvider<OAuthToken>, ClientCredentialsTokenProvider<OAuthToken>>(); // 注册生成的API客户端,注入TokenProvider并添加OAuth消息处理器 services.AddHttpClient<YourGeneratedApiClient>(client => { client.BaseAddress = new Uri(context.Configuration["ApiBaseUrl"]!); }) .AddHttpMessageHandler(provider => new OAuthAuthorizationHandler(provider.GetRequiredService<TokenProvider<OAuthToken>>())); }); var host = builder.Build(); await host.RunAsync();
4. TokenProvider实现示例
如果生成代码未提供默认实现,可自行实现接口:
public class ClientCredentialsTokenProvider : TokenProvider<OAuthToken> { private readonly HttpClient _httpClient; private readonly OAuthClientOptions _options; private OAuthToken? _currentToken; public ClientCredentialsTokenProvider(HttpClient httpClient, IOptions<OAuthClientOptions> options) { _httpClient = httpClient; _options = options.Value; } public async Task<OAuthToken> GetTokenAsync(CancellationToken cancellationToken = default) { // 检查token有效性,过期则重新获取 if (_currentToken == null || DateTime.UtcNow >= _currentToken.ExpiresAt) { var request = new HttpRequestMessage(HttpMethod.Post, _options.TokenEndpoint) { Content = new FormUrlEncodedContent(new Dictionary<string, string> { {"grant_type", "client_credentials"}, {"client_id", _options.ClientId}, {"client_secret", _options.ClientSecret} }) }; var response = await _httpClient.SendAsync(request, cancellationToken); response.EnsureSuccessStatusCode(); _currentToken = await response.Content.ReadFromJsonAsync<OAuthToken>(cancellationToken); if (_currentToken != null) { // 预留60秒缓冲时间,避免token过期 _currentToken.ExpiresAt = DateTime.UtcNow.AddSeconds(_currentToken.ExpiresIn - 60); } } return _currentToken ?? throw new InvalidOperationException("Failed to obtain OAuth token"); } }
5. OAuth请求消息处理器
自动为API请求添加Authorization头:
public class OAuthAuthorizationHandler : DelegatingHandler { private readonly TokenProvider<OAuthToken> _tokenProvider; public OAuthAuthorizationHandler(TokenProvider<OAuthToken> tokenProvider) { _tokenProvider = tokenProvider; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var token = await _tokenProvider.GetTokenAsync(cancellationToken); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); return await base.SendAsync(request, cancellationToken); } }
内容的提问来源于stack exchange,提问作者mmm
相关产品推荐
相关产品推荐

