using DD.Persistence.Models.Configurations; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Headers; using System.Security.Claims; using System.Text.Json; namespace DD.Persistence.Client.Helpers; /// /// Класс, позволяющий генерировать api-token /// public static class ApiTokenHelper { /// /// Метод авториации /// /// /// /// public static async Task Authorize(this HttpClient httpClient, IConfiguration configuration) { var authUser = configuration .GetSection(nameof(AuthUser)) .Get()!; var needUseKeyCloak = configuration .GetSection("NeedUseKeyCloak") .Get()!; var keycloakGetTokenUrl = configuration.GetSection("KeycloakGetTokenUrl").Get() ?? string.Empty; var jwtToken = needUseKeyCloak ? await authUser.CreateKeyCloakJwtToken(keycloakGetTokenUrl) : authUser.CreateDefaultJwtToken(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken); } /// /// Авторизация через собственный jwt-токен /// /// /// private static string CreateDefaultJwtToken(this AuthUser authUser) { var nameIdetifier = Guid.NewGuid().ToString(); var claims = new List() { new(ClaimTypes.NameIdentifier, nameIdetifier), new("client_id", authUser.ClientId), new("username", authUser.Username), new("password", authUser.Password), new("grant_type", authUser.GrantType), new(ClaimTypes.NameIdentifier.ToString(), Guid.NewGuid().ToString()) }; var tokenDescriptor = new SecurityTokenDescriptor { Issuer = JwtParams.Issuer, Audience = JwtParams.Audience, Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = new SigningCredentials(JwtParams.SecurityKey, SecurityAlgorithms.HmacSha256Signature) }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } /// /// Авторизация через jwt-токен keycloak /// /// /// /// private static async Task CreateKeyCloakJwtToken(this AuthUser authUser, string keycloakGetTokenUrl) { var sharedClient = new HttpClient(); var parameters = new Dictionary { { "username", authUser.Username }, { "password", authUser.Password }, { "client_id", authUser.ClientId }, { "grant_type", authUser.GrantType }, }; var encodedContent = new FormUrlEncodedContent(parameters); using HttpResponseMessage response = await sharedClient.PostAsync(keycloakGetTokenUrl, encodedContent); if (response.IsSuccessStatusCode == true) { var data = await response.Content.ReadAsStreamAsync(); var token = JsonSerializer.Deserialize(data)!; return token.AccessToken; } return String.Empty; } }