diff --git a/IdentityServer.Wrapper/Constants/ApiRoutes.cs b/IdentityServer.Wrapper/Constants/ApiRoutes.cs new file mode 100644 index 0000000..7a821ca --- /dev/null +++ b/IdentityServer.Wrapper/Constants/ApiRoutes.cs @@ -0,0 +1,9 @@ +namespace IdentityServer.Wrapper.Constants +{ + internal struct ApiRoutes + { + public const string + Authentication = "identity/authenticate?UserName={0}&Password={1}", + Authorization = "identity/authorize?Token={0}"; + } +} diff --git a/IdentityServer.Wrapper/DependencyInjectionExtension.cs b/IdentityServer.Wrapper/DependencyInjectionExtension.cs new file mode 100644 index 0000000..df56479 --- /dev/null +++ b/IdentityServer.Wrapper/DependencyInjectionExtension.cs @@ -0,0 +1,15 @@ +using IdentityServer.Wrapper.Models; +using IdentityServer.Wrapper.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace IdentityServer.Wrapper +{ + public static class DependencyInjectionExtension + { + public static void UseIdentityService(this IServiceCollection services, string baseAddress) + { + services.AddSingleton(new ServiceConfiguration(baseAddress)); + services.AddHttpClient(); + } + } +} diff --git a/IdentityServer.Wrapper/IdentityServer.Wrapper.csproj b/IdentityServer.Wrapper/IdentityServer.Wrapper.csproj new file mode 100644 index 0000000..a69da54 --- /dev/null +++ b/IdentityServer.Wrapper/IdentityServer.Wrapper.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0 + + + + + + + + + + diff --git a/IdentityServer.Wrapper/Models/ServiceConfiguration.cs b/IdentityServer.Wrapper/Models/ServiceConfiguration.cs new file mode 100644 index 0000000..9a29547 --- /dev/null +++ b/IdentityServer.Wrapper/Models/ServiceConfiguration.cs @@ -0,0 +1,12 @@ +namespace IdentityServer.Wrapper.Models +{ + internal class ServiceConfiguration + { + public string BaseAddress { get; } + + public ServiceConfiguration(string baseAddress) + { + BaseAddress = baseAddress; + } + } +} diff --git a/IdentityServer.Wrapper/Services/IIdentityService.cs b/IdentityServer.Wrapper/Services/IIdentityService.cs new file mode 100644 index 0000000..88af25f --- /dev/null +++ b/IdentityServer.Wrapper/Services/IIdentityService.cs @@ -0,0 +1,11 @@ +using IdentityServer.PublishedLanguage.Dto; +using System.Threading.Tasks; + +namespace IdentityServer.Wrapper.Services +{ + public interface IIdentityService + { + Task Authenticate(string userName, string password); + Task Authorize(string token); + } +} diff --git a/IdentityServer.Wrapper/Services/IdentityService.cs b/IdentityServer.Wrapper/Services/IdentityService.cs new file mode 100644 index 0000000..88fbc9b --- /dev/null +++ b/IdentityServer.Wrapper/Services/IdentityService.cs @@ -0,0 +1,80 @@ +using IdentityServer.PublishedLanguage.Dto; +using IdentityServer.Wrapper.Constants; +using IdentityServer.Wrapper.Models; +using Newtonsoft.Json; +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; + +namespace IdentityServer.Wrapper.Services +{ + internal class IdentityService : IIdentityService + { + private const string _contentType = "application/json"; + private readonly HttpClient _httpClient; + + public IdentityService(HttpClient httpClient, ServiceConfiguration configuration) + { + httpClient.BaseAddress = new Uri(configuration.BaseAddress); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_contentType)); + + _httpClient = httpClient; + } + + public async Task Authenticate(string userName, string password) + { + var route = string.Format(ApiRoutes.Authentication, userName, password); + var result = await ExecutePostRequest(route); + return result; + } + + public async Task Authorize(string token) + { + var route = string.Format(ApiRoutes.Authorization, token); + var result = await ExecutePostRequest(route); + return result; + } + + #region Private methods + private async Task ExecuteGetRequest(string route) where T : class + { + using (var response = await _httpClient.GetAsync(route)) + { + if (!response.IsSuccessStatusCode) + throw new Exception($"Error: StatusCode: {response.StatusCode}; Reason: {response.ReasonPhrase}"); + + var result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + return result; + } + } + + private async Task ExecutePostRequest(string route) where R : class + { + HttpContent content = new StringContent(JsonConvert.SerializeObject(string.Empty), Encoding.UTF8, _contentType); + using (var response = await _httpClient.PostAsync(route, content)) + { + if (!response.IsSuccessStatusCode) + throw new Exception($"Error: StatusCode: {response.StatusCode}; Reason: {response.ReasonPhrase}"); + + var result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + return result; + } + } + + private async Task ExecutePostRequest(string route, B body) where R : class where B : class + { + HttpContent content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, _contentType); + using (var response = await _httpClient.PostAsync(route, content)) + { + if (!response.IsSuccessStatusCode) + throw new Exception($"Error: StatusCode: {response.StatusCode}; Reason: {response.ReasonPhrase}"); + + var result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + return result; + } + } + #endregion + } +} diff --git a/IdentityServer.sln b/IdentityServer.sln index 7b78912..1d86b46 100644 --- a/IdentityServer.sln +++ b/IdentityServer.sln @@ -26,6 +26,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityServer.Domain.Data" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityServer.PublishedLanguage", "IdentityServer.PublishedLanguage\IdentityServer.PublishedLanguage.csproj", "{67B4D1FF-D02E-4DA6-9FB8-F71667360448}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdentityServer.Wrapper", "IdentityServer.Wrapper\IdentityServer.Wrapper.csproj", "{F6FEC33B-C79E-4484-B356-9C7F1A5E5D95}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -52,6 +54,10 @@ Global {67B4D1FF-D02E-4DA6-9FB8-F71667360448}.Debug|Any CPU.Build.0 = Debug|Any CPU {67B4D1FF-D02E-4DA6-9FB8-F71667360448}.Release|Any CPU.ActiveCfg = Release|Any CPU {67B4D1FF-D02E-4DA6-9FB8-F71667360448}.Release|Any CPU.Build.0 = Release|Any CPU + {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -62,6 +68,7 @@ Global {5890B079-3CB0-4AD6-8809-BB2E081590B1} = {5A8FF505-3E4D-4258-BC3E-CACD74A7B98C} {CE81A435-49AC-4544-A381-FAC91BEB3C49} = {5A8FF505-3E4D-4258-BC3E-CACD74A7B98C} {67B4D1FF-D02E-4DA6-9FB8-F71667360448} = {5A8FF505-3E4D-4258-BC3E-CACD74A7B98C} + {F6FEC33B-C79E-4484-B356-9C7F1A5E5D95} = {5A8FF505-3E4D-4258-BC3E-CACD74A7B98C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E93DC46D-9C55-4A05-B299-497CDD90747E}