From be3cd1ac85fca17693118f370f979a295d152305 Mon Sep 17 00:00:00 2001 From: Frede Hundewadt Date: Wed, 14 Dec 2022 12:01:50 +0100 Subject: [PATCH] initial commit --- AzureAuthStore.cs | 58 ++++++++++++++++++++++++++++ AzureToken.cs | 39 +++++++++++++++++++ AzureTokenDto.cs | 40 ++++++++++++++++++++ AzureTokenFetcher.cs | 45 ++++++++++++++++++++++ AzureTokenHttpRequest.cs | 61 ++++++++++++++++++++++++++++++ AzureTokenMapper.cs | 50 +++++++++++++++++++++++++ FCS.Lib.Azure.csproj | 77 ++++++++++++++++++++++++++++++++++++++ IAzureTokenFetcher.cs | 35 +++++++++++++++++ Properties/AssemblyInfo.cs | 35 +++++++++++++++++ README.md | 41 ++++++++++++++++++++ ResponseView.cs | 37 ++++++++++++++++++ app.config | 19 ++++++++++ packages.config | 26 +++++++++++++ 13 files changed, 563 insertions(+) create mode 100644 AzureAuthStore.cs create mode 100644 AzureToken.cs create mode 100644 AzureTokenDto.cs create mode 100644 AzureTokenFetcher.cs create mode 100644 AzureTokenHttpRequest.cs create mode 100644 AzureTokenMapper.cs create mode 100644 FCS.Lib.Azure.csproj create mode 100644 IAzureTokenFetcher.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 ResponseView.cs create mode 100644 app.config create mode 100644 packages.config 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