using System; using System.Net.Http; using System.Threading.Tasks; using IdentityModel.Client; using Microsoft.Extensions.Logging; using xCommons.Extensions; using xExceptions.Constants; using xExceptions.Models; using xIdentityModels.Extensions; using xIdentityModels.Models; using xIds.Extensions; using static IdentityModel.OidcConstants; namespace xIds.Providers { public partial class XIdentityManager { // #region Identity Actions ... /// /// Request for Discovery Document /// /// an instance of DiscoveryDocumentResponse public async Task RequestDiscoveryDocument() { // var httpClient = GetHttpClient(); var result = httpClient .GetDiscoveryDocumentAsync(IdentityResourceConfiguration.Authority) .ContinueWith(docTask => { // httpClient.Dispose(); return docTask.Result; }); // return await result; } /// /// Request AccessToken for Specific XApiScope /// /// a member of XApiScope /// an instance of TokenResponse public async Task RequestScopeAccessToken( string scope ) { // // Validate Args ... if (scope.IsNullOrEmpty()) { XException.InvalidArgs.Throw(); } // // Retrieve Disco Doc ... var discoDoc = await RequestDiscoveryDocument(); if (discoDoc.IsError) { XException.ActionFailed.Throw(); } // var request = new ClientCredentialsTokenRequest { Address = discoDoc.TokenEndpoint, GrantType = GrantTypes.ClientCredentials, ClientId = IdentityResourceConfiguration.ClientId, ClientSecret = IdentityResourceConfiguration.ClientSecret, Scope = scope }; // var httpClient = GetHttpClient(); var result = await httpClient .RequestClientCredentialsTokenAsync(request) .ContinueWith(response => { // httpClient.Dispose(); return response.Result; }); // return result; } /// /// Authenticate a User /// /// an instance of XLoginRequest class which represent Authentication requirements /// an instance of TokenResponse public async Task Authenticate( XLoginRequest model ) { // // Validate Args ... ValidationProvider .GroupValidationBuilder() .AddNotNull(model) .AddNotEmpty( model.UserSelectBy, model.Password ) .ValidateGroup(); // // Retrieve Disco Doc ... var discoDoc = await RequestDiscoveryDocument(); if (discoDoc.IsError) { XException.ActionFailed.Throw(); } // // Create Request ... var request = new PasswordTokenRequest { // Address = discoDoc.TokenEndpoint, // GrantType = GrantTypes.ClientCredentials, ClientId = IdentityResourceConfiguration.ClientId, ClientSecret = IdentityResourceConfiguration.ClientSecret, // UserName = model.UserSelectBy, Password = model.Password, // // Pass Device to Request ... Parameters = { { "force", false.ToJSON () } } }; // var httpClient = GetHttpClient(); var result = await httpClient .RequestPasswordTokenAsync(request) .ContinueWith(response => { // httpClient.Dispose(); return response.Result; }); // return result; } /// /// Do Login based on XLoginRequest /// /// an instance of XLoginRequest class which represent Authentication requirements /// an instance of XLoginResponse public async Task Login( XLoginRequest model ) { // // Validate Args ... ValidationProvider .GroupValidationBuilder() .AddNotNull(model, model.Device) .AddNotEmpty( model.UserSelectBy, model.Password ) .ValidateGroup(); // // Get Token Response ... // // Retrieve Disco Doc ... var discoDoc = await RequestDiscoveryDocument(); Logger.LogInformation($"discoDoc: {discoDoc.ToJSON()}"); if (discoDoc.IsError) { XException.ActionFailed.Throw(); } // // Create Request ... var request = new PasswordTokenRequest { // Address = discoDoc.TokenEndpoint, // GrantType = GrantTypes.ClientCredentials, ClientId = IdentityResourceConfiguration.ClientId, ClientSecret = IdentityResourceConfiguration.ClientSecret, // UserName = model.UserSelectBy, Password = model.Password, // // Pass Device to Request ... Parameters = { { "force", false.ToJSON () }, { "device", model.Device.ToJSON () }, { "language", model.Language } } }; // var httpClient = GetHttpClient(); var authResponse = await httpClient .RequestPasswordTokenAsync(request) .ContinueWith(response => { // httpClient.Dispose(); return response.Result; }); // // Check If Response Has Error ... Logger.LogInformation($"AuthResponse: {authResponse.ToJSON()}"); // if (authResponse.IsError) { throw authResponse.GetException(); } // // Create XLoginResponse Model ... var result = authResponse.CreateXLoginResponse(); // // Get ans Set User Profile ... result.Profile = await GetUserProfileAsync(model.UserSelectBy, model.UserSelectBy); // return result; } /// /// Refresh Tokens /// /// Authentication Tokens, instance of XTokenResponse /// an instance of XTokenResponse public async Task RefreshTokens( XTokenResponse model ) { // // Validate Args ... ValidationProvider .GroupValidationBuilder() .AddNotNull(model) .AddNotEmpty( model.AccessToken, model.RefreshToken ) .ValidateGroup(); // var authResponse = await RequestDiscoveryDocument() .ContinueWith((discoTask) => { // var discoDoc = discoTask.Result; if (discoDoc.IsError) { XException.ActionFailed.Throw(); } // using (var httpClient = GetHttpClient()) { return httpClient.RequestRefreshTokenAsync(new RefreshTokenRequest { // Address = discoDoc.TokenEndpoint, GrantType = GrantTypes.RefreshToken, ClientId = IdentityResourceConfiguration.ClientId, ClientSecret = IdentityResourceConfiguration.ClientSecret, RefreshToken = model.RefreshToken }).Result; } }); // // Check If Response Has Error ... if (authResponse.IsError) { // XError error = authResponse.ErrorDescription.FromJSON(); throw error.ToException(); } // // Create XLoginResponse Model ... var result = authResponse.CreateXTokenResponse(); // return result; } #endregion // #region Requirements ... /// /// Get an Instance of Http Client /// /// an instance of HttpClient public HttpClient GetHttpClient() { // HttpClient httpClient = null; httpClient = new HttpClient(); var httpClientHandler = new HttpClientHandler() { ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { // Logger.LogInformation( $"SSL Handler: {Environment.NewLine} sender: {sender}, {Environment.NewLine} cert: {cert}, {Environment.NewLine} chain: {chain}, {Environment.NewLine} sslPolicyErrors: {sslPolicyErrors}" ); // return true; }, ClientCertificateOptions = ClientCertificateOption.Manual, }; // httpClient = new HttpClient(httpClientHandler); // return httpClient; } #endregion } }