43 lines
1.6 KiB
C#
43 lines
1.6 KiB
C#
using System.Net.Http.Json;
|
|
using System.Text.Json.Serialization;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace Tnsu.ApprovalRoute.Infrastructure.TnsuPortal;
|
|
|
|
public sealed class TnsuPortalTokenProvider(HttpClient httpClient, IOptions<TnsuPortalOptions> options)
|
|
{
|
|
private string? _cachedToken;
|
|
private DateTimeOffset _expiresAt = DateTimeOffset.MinValue;
|
|
|
|
public async Task<string> GetAccessTokenAsync(CancellationToken cancellationToken)
|
|
{
|
|
if (_cachedToken is not null && DateTimeOffset.UtcNow < _expiresAt)
|
|
return _cachedToken;
|
|
|
|
var opts = options.Value;
|
|
var response = await httpClient.PostAsync(
|
|
$"https://login.microsoftonline.com/{opts.TenantId}/oauth2/v2.0/token",
|
|
new FormUrlEncodedContent(new Dictionary<string, string>
|
|
{
|
|
["grant_type"] = "client_credentials",
|
|
["client_id"] = opts.ClientId,
|
|
["client_secret"] = opts.ClientSecret,
|
|
["scope"] = opts.Scope
|
|
}),
|
|
cancellationToken);
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
var payload = await response.Content.ReadFromJsonAsync<TokenResponse>(cancellationToken)
|
|
?? throw new InvalidOperationException("Не удалось получить токен для api.tnsu.kz.");
|
|
|
|
_cachedToken = payload.AccessToken;
|
|
_expiresAt = DateTimeOffset.UtcNow.AddSeconds(payload.ExpiresIn - 60);
|
|
|
|
return _cachedToken;
|
|
}
|
|
|
|
private sealed record TokenResponse(
|
|
[property: JsonPropertyName("access_token")] string AccessToken,
|
|
[property: JsonPropertyName("expires_in")] int ExpiresIn);
|
|
}
|