using Microsoft.Extensions.Configuration; using Microsoft.Identity.Client; using UniVerse.Application.Interfaces; using UniVerse.Domain.Exceptions; namespace UniVerse.Infrastructure.ExternalServices; public class MicrosoftAuthClient : IMicrosoftAuthClient { private readonly IConfiguration _config; public MicrosoftAuthClient(IConfiguration config) { _config = config; } public async Task ExchangeAuthorizationCodeAsync( string authorizationCode, string redirectUri, CancellationToken cancellationToken = default) { var tenantId = _config["AzureAd:TenantId"]; var clientId = _config["AzureAd:ClientId"]; var clientSecret = _config["AzureAd:ClientSecret"]; var instance = _config["AzureAd:Instance"] ?? "https://login.microsoftonline.com/"; if (string.IsNullOrWhiteSpace(tenantId) || string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret)) throw new UnauthorizedException("Аутентификация Microsoft не настроена (AzureAd:TenantId/ClientId/ClientSecret)."); var authority = $"{instance.TrimEnd('/')}/{tenantId}"; var app = ConfidentialClientApplicationBuilder.Create(clientId) .WithClientSecret(clientSecret) .WithAuthority(new Uri(authority)) .WithRedirectUri(redirectUri) .Build(); try { var result = await app.AcquireTokenByAuthorizationCode(["User.Read"], authorizationCode) .ExecuteAsync(cancellationToken); return new MicrosoftTokenResult(result.IdToken); } catch (MsalException ex) { throw new UnauthorizedException($"Ошибка аутентификации Microsoft: {ex.Message}"); } } }