diff --git a/AzureAuthStore.cs b/AzureAuthStore.cs new file mode 100644 index 0000000..b4f15d1 --- /dev/null +++ b/AzureAuthStore.cs @@ -0,0 +1,58 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-10-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +namespace FCS.Lib.Azure +{ + public class AzureAuthStore + { + public AzureAuthStore( + string azureLoginUrl, string azureOAuthEndpoint, string azureTenantId, + string azureClientId, string azureGrantType, string azureSecret, + string azureLoginScope) + { + AzureLoginUrl = azureLoginUrl; + AzureOAuthEndpoint = azureOAuthEndpoint; + AzureTenantId = azureTenantId; + AzureClientId = azureClientId; + AzureGrantType = azureGrantType; + AzureSecret = azureSecret; + AzureLoginScope = azureLoginScope; + } + + protected string AzureLoginUrl { get; set; } + protected string AzureOAuthEndpoint { get; set; } + protected string AzureTenantId { get;} + public string AzureClientId { get;} + public string AzureGrantType { get;} + public string AzureSecret { get; } + public string AzureLoginScope { get; } + + public string AzureTokenEndpoint() + { + return $"{AzureLoginUrl}/{AzureTenantId}/{AzureOAuthEndpoint}"; + } + } +} \ No newline at end of file diff --git a/AzureToken.cs b/AzureToken.cs new file mode 100644 index 0000000..53ea0a6 --- /dev/null +++ b/AzureToken.cs @@ -0,0 +1,39 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-10-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +namespace FCS.Lib.Azure +{ + public class AzureToken + { + public string TokenType { get; set; } = ""; + public string AccessToken { get; set; } = ""; + public long Expires { get; set; } + public bool HasExpired(long timestamp) + { + return timestamp > Expires; + } + } +} \ No newline at end of file diff --git a/AzureTokenDto.cs b/AzureTokenDto.cs new file mode 100644 index 0000000..2a87fc0 --- /dev/null +++ b/AzureTokenDto.cs @@ -0,0 +1,40 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-08-2022 +// +// Last Modified By : FH +// Last Modified On : 05-08-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + + +using System.Text.Json.Serialization; + +namespace FCS.Lib.Azure +{ + public class AzureTokenDto + { + [JsonPropertyName("token_type")] public string TokenType { get; set; } + [JsonPropertyName("expires_in")] public long ExpiresIn { get; set; } + [JsonPropertyName("ext_expires_in")] public long ExtExpiresIn { get; set; } + [JsonPropertyName("access_token")] public string AccessToken { get; set; } + + } +} \ No newline at end of file diff --git a/AzureTokenFetcher.cs b/AzureTokenFetcher.cs new file mode 100644 index 0000000..5b7c6f2 --- /dev/null +++ b/AzureTokenFetcher.cs @@ -0,0 +1,45 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-10-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +using System.Threading.Tasks; + +namespace FCS.Lib.Azure +{ + public class AzureTokenFetcher : IAzureTokenFetcher + { + private readonly AzureAuthStore _config; + public AzureTokenFetcher(AzureAuthStore config) + { + _config = config; + } + + public async Task FetchAzureToken() + { + var result = await AzureTokenHttpRequest.RequestTokenAsync(_config).ConfigureAwait(true); + return !result.IsSuccessStatusCode ? new AzureToken{Expires = -1} : new AzureTokenMapper().MapAzureToken(result.Message); + } + } +} \ No newline at end of file diff --git a/AzureTokenHttpRequest.cs b/AzureTokenHttpRequest.cs new file mode 100644 index 0000000..bbe5088 --- /dev/null +++ b/AzureTokenHttpRequest.cs @@ -0,0 +1,61 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-10-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +namespace FCS.Lib.Azure +{ + public class AzureTokenHttpRequest + { + public static async Task RequestTokenAsync(AzureAuthStore azureAuth) + { + var credentials = new Dictionary + { + { "grant_type", azureAuth.AzureGrantType }, + { "client_id", azureAuth.AzureClientId }, + { "client_secret", azureAuth.AzureSecret }, + { "scope", azureAuth.AzureLoginScope} + }; + + using var client = new HttpClient(); + + var content = new FormUrlEncodedContent(credentials); + + var responseMessage = await client.PostAsync(azureAuth.AzureTokenEndpoint(), content).ConfigureAwait(true); + + var azureResponse = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(true); + + return new ResponseView + { + Code = responseMessage.StatusCode, + IsSuccessStatusCode = responseMessage.IsSuccessStatusCode, + Message = azureResponse + }; + } + } +} diff --git a/AzureTokenMapper.cs b/AzureTokenMapper.cs new file mode 100644 index 0000000..904f200 --- /dev/null +++ b/AzureTokenMapper.cs @@ -0,0 +1,50 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-08-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + + +using System; +using System.Text.Json; +using FCS.Lib.Utility; + +namespace FCS.Lib.Azure +{ + public class AzureTokenMapper + { + public AzureToken MapAzureToken(string json) + { + if(string.IsNullOrWhiteSpace(json)) + throw new ArgumentNullException(nameof(json)); + + var token = JsonSerializer.Deserialize(json); + return token == null ? null : new AzureToken + { + AccessToken = token.AccessToken, + Expires = Mogrify.CurrentDateTimeToTimeStamp() + token.ExtExpiresIn - 600, + TokenType = token.TokenType + }; + } + } +} \ No newline at end of file diff --git a/FCS.Lib.Azure.csproj b/FCS.Lib.Azure.csproj new file mode 100644 index 0000000..6c2eeec --- /dev/null +++ b/FCS.Lib.Azure.csproj @@ -0,0 +1,77 @@ + + + + + 10.0 + + + Debug + AnyCPU + {63F067FE-925B-4076-86F5-F630F3E5A75B} + Library + Properties + FCS.Lib.Azure + FCS.Lib.Azure + v4.8 + 512 + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + {1F1FECFD-E07E-4B5C-A7F9-67FB89EE94A3} + FCS.Lib.Utility + + + + + + + ..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Net.Http.dll + + + ..\..\inno\inno.api.v2\packages\System.Text.Json.6.0.4\lib\net461\System.Text.Json.dll + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/IAzureTokenFetcher.cs b/IAzureTokenFetcher.cs new file mode 100644 index 0000000..f50cc3f --- /dev/null +++ b/IAzureTokenFetcher.cs @@ -0,0 +1,35 @@ +// *********************************************************************** +// Assembly : FCS.Lib.Azure +// Author : FH +// Created : 05-10-2022 +// +// Last Modified By : FH +// Last Modified On : 05-10-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +using System.Threading.Tasks; + +namespace FCS.Lib.Azure +{ + public interface IAzureTokenFetcher + { + Task FetchAzureToken(); + } +} \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a42ae73 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FCS.Lib.Azure")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FCS.Lib.Azure")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("63f067fe-925b-4076-86f5-f630f3e5a75b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/README.md b/README.md index 6258f84..306ed5f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,43 @@ # fcs-azure Library to aquire Azure access token + +Sample call +``` +public class Program +{ + static void Main(string[] args) + { + var settings = new MySettings(); + + var authStore = new AzureAuthStore(settings.LoginUrl, settings.OAuthEndpoint, settings.TenantId, + settings.ClientId, settings.GrantType, settings.ClientSecret, settings.LoginScope); + + var tokenFetcher = new AzureTokenFetcher(authStore); + + // normally called async - but this is only a test + var token = tokenFetcher.FetchAzureToken().Result; + + var ts1 = Mogrify.CurrentDateTimeToTimeStamp(); + var ts2 = Mogrify.DateTimeToTimeStamp(DateTime.Now.AddHours(+2)); + + Console.WriteLine($"AccessToken: {token.AccessToken}"); + Console.WriteLine($"Expires : {token.Expires}"); + Console.WriteLine($"TokenType : {token.TokenType}"); + Console.WriteLine($"HasExpired : {DateTime.Now} {ts1} {token.HasExpired(ts1)}"); + Console.WriteLine($"HasExpired : {DateTime.Now.AddHours(+2)} {ts2} {token.HasExpired(ts2)}"); + Console.ReadKey(); + } +} + +internal sealed class MySettings +{ + public string LoginUrl => "https://login.microsoftonline.com"; + public string OAuthEndpoint => "oauth2/v2.0/token"; + public string GrantType => "client_credentials"; + public string LoginScope => ""; + public string TenantId => ""; + public string ClientId => ""; + public string ClientSecret => ""; +} + +``` diff --git a/ResponseView.cs b/ResponseView.cs new file mode 100644 index 0000000..a558076 --- /dev/null +++ b/ResponseView.cs @@ -0,0 +1,37 @@ +// *********************************************************************** +// Assembly : Inno.Views +// Author : FH +// Created : 01-01-2022 +// +// Last Modified By : FH +// Last Modified On : 04-18-2022 +// *********************************************************************** +// +// Copyright (C) 2022 FCS Frede's Computer Services. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see [https://www.gnu.org/licenses] +// +// +// *********************************************************************** + +using System.Net; + +namespace FCS.Lib.Azure +{ + public class ResponseView + { + public HttpStatusCode Code { get; set; } + public bool IsSuccessStatusCode { get; set; } + public string Message { get; set; } = ""; + } +} \ No newline at end of file diff --git a/app.config b/app.config new file mode 100644 index 0000000..3f90ec0 --- /dev/null +++ b/app.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..fe01191 --- /dev/null +++ b/packages.config @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file