From 7abb3a6c8a9c956106143ee3cc5a18ab6ea550c0 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 10:47:55 +0200 Subject: [PATCH 1/9] =?UTF-8?q?chore(deps):=20NuGet-Paketversionen=20aktua?= =?UTF-8?q?lisieren=20und=20DigitalData.Auth.Client=20hinzuf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EnvelopeGenerator.GeneratorAPI.csproj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index e76957a6..95325e67 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -19,11 +19,12 @@ + - + - - + + From e2bdc73b76c54579c69d159f6f6d578c8cb02d43 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 14:15:45 +0200 Subject: [PATCH 2/9] =?UTF-8?q?chore:=20auth-hub-client=20hinzuf=C3=BCgen?= =?UTF-8?q?=20und=20konfigurieren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EnvelopeGenerator.GeneratorAPI.csproj | 2 +- EnvelopeGenerator.GeneratorAPI/Program.cs | 4 +++- .../appsettings.Development.json | 10 ++++++++++ EnvelopeGenerator.GeneratorAPI/appsettings.json | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index 95325e67..2b88fcca 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -19,7 +19,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index 77ee0bab..6ba72940 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -1,6 +1,5 @@ using DigitalData.Core.API; using DigitalData.Core.Application; -using DigitalData.UserManager.Application; using EnvelopeGenerator.Infrastructure; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Localization; @@ -10,6 +9,7 @@ using Scalar.AspNetCore; using Microsoft.OpenApi.Models; using DigitalData.UserManager.DependencyInjection; using EnvelopeGenerator.Application; +using DigitalData.Auth.Client; var builder = WebApplication.CreateBuilder(args); @@ -85,6 +85,8 @@ builder.Services.AddOpenApi(); var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json."); builder.Services.AddDbContext(options => options.UseSqlServer(connStr)); +builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams")); + // Authentication builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => diff --git a/EnvelopeGenerator.GeneratorAPI/appsettings.Development.json b/EnvelopeGenerator.GeneratorAPI/appsettings.Development.json index 0c208ae9..7525e080 100644 --- a/EnvelopeGenerator.GeneratorAPI/appsettings.Development.json +++ b/EnvelopeGenerator.GeneratorAPI/appsettings.Development.json @@ -4,5 +4,15 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + "AuthClientParams": { + "Url": "https://localhost:7192/auth-hub", + "PublicKeys": [ + { + "Issuer": "auth.digitaldata.works", + "Audience": "sign-flow-gen.digitaldata.works" + } + ], + "RetryDelay": "00:00:05" } } diff --git a/EnvelopeGenerator.GeneratorAPI/appsettings.json b/EnvelopeGenerator.GeneratorAPI/appsettings.json index 734a3dcb..d7c6e9bd 100644 --- a/EnvelopeGenerator.GeneratorAPI/appsettings.json +++ b/EnvelopeGenerator.GeneratorAPI/appsettings.json @@ -20,5 +20,15 @@ "User": "(&(objectClass=user)(sAMAccountName=*))", "Group": "(&(objectClass=group)(samAccountName=*))" } + }, + "AuthClientParams": { + "Url": "https://localhost:7192/auth-hub", + "PublicKeys": [ + { + "Issuer": "auth.digitaldata.works", + "Audience": "sign-flow-gen.digitaldata.works" + } + ], + "RetryDelay": "00:00:05" } } From 27e9de4709b9bc4065905c36cc042a92b40b8c7f Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 15:02:49 +0200 Subject: [PATCH 3/9] chore(Core.Abstraction): Aktualisiert auf 3.4.4 --- .../EnvelopeGenerator.Application.csproj | 2 +- EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj | 2 +- .../EnvelopeGenerator.GeneratorAPI.csproj | 2 +- .../EnvelopeGenerator.Infrastructure.csproj | 2 +- EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj | 2 +- .../EnvelopeGenerator.Tests.Application.csproj | 2 +- EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index f032eed8..a14714ed 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -13,7 +13,7 @@ - + diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index 8a430d70..156a8d44 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index 2b88fcca..5945c0c9 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -25,7 +25,7 @@ - + diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index f18a5f72..cea3cddf 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj index 175074cf..21591d1f 100644 --- a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj +++ b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj @@ -19,7 +19,7 @@ - + diff --git a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj index c6e028c7..61e7c13e 100644 --- a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj +++ b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj @@ -23,7 +23,7 @@ - + diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 761e4780..bfc6d63c 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -2101,7 +2101,7 @@ - + From dcdf0844cbcbe01e4ef5c28c699127c21b74d766 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 15:08:07 +0200 Subject: [PATCH 4/9] feat(Program): DeferredServiceProvider-Instanz erstellen und Fabrik einstellen --- EnvelopeGenerator.GeneratorAPI/Program.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index 6ba72940..1d2c3522 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -10,11 +10,14 @@ using Microsoft.OpenApi.Models; using DigitalData.UserManager.DependencyInjection; using EnvelopeGenerator.Application; using DigitalData.Auth.Client; +using DigitalData.Core.Abstractions; var builder = WebApplication.CreateBuilder(args); var config = builder.Configuration; +var deferredProvider = new DeferredServiceProvider(); + builder.Services.AddControllers(); //CORS Policy @@ -116,6 +119,8 @@ builder.Services var app = builder.Build(); +deferredProvider.Factory = () => app.Services; + app.MapOpenApi(); // Configure the HTTP request pipeline. From 875ff95278118a14b5fdafc7def63009ba87f347 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 15:49:40 +0200 Subject: [PATCH 5/9] =?UTF-8?q?feat(AuthTokenKeys):=20Erstellt,=20um=20Par?= =?UTF-8?q?ameter=20f=C3=BCr=20Authentifizierungs-Tokens=20zu=20konfigurie?= =?UTF-8?q?ren.=20=20-=20AuthTokenKeys=20aus=20der=20Konfiguration=20in=20?= =?UTF-8?q?Program.cs=20lesen.=20=20-=20Upgrade=20von=20Core.Abstractions?= =?UTF-8?q?=20auf=203.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EnvelopeGenerator.Application.csproj | 2 +- .../EnvelopeGenerator.Domain.csproj | 2 +- .../EnvelopeGenerator.GeneratorAPI.csproj | 2 +- .../Models/AuthTokenKeys.cs | 28 +++++++++++++++++++ EnvelopeGenerator.GeneratorAPI/Program.cs | 3 ++ .../appsettings.json | 6 ++++ .../EnvelopeGenerator.Infrastructure.csproj | 2 +- .../EnvelopeGenerator.Terminal.csproj | 2 +- ...EnvelopeGenerator.Tests.Application.csproj | 2 +- .../EnvelopeGenerator.Web.csproj | 2 +- 10 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 EnvelopeGenerator.GeneratorAPI/Models/AuthTokenKeys.cs diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index a14714ed..deaf9710 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -13,7 +13,7 @@ - + diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index 156a8d44..60dd3bd2 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index 5945c0c9..30539d93 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -25,7 +25,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/Models/AuthTokenKeys.cs b/EnvelopeGenerator.GeneratorAPI/Models/AuthTokenKeys.cs new file mode 100644 index 00000000..75bf927a --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Models/AuthTokenKeys.cs @@ -0,0 +1,28 @@ +namespace EnvelopeGenerator.GeneratorAPI.Models; + +/// +/// Represents the keys and default values used for authentication token handling +/// within the Envelope Generator API. +/// +public class AuthTokenKeys +{ + /// + /// Gets the name of the cookie used to store the authentication token. + /// + public string Cookie { get; init; } = "AuthToken"; + + /// + /// Gets the name of the query string parameter used to pass the authentication token. + /// + public string QueryString { get; init; } = "AuthToken"; + + /// + /// Gets the expected issuer value for the authentication token. + /// + public string Issuer { get; init; } = "auth.digitaldata.works"; + + /// + /// Gets the expected audience value for the authentication token. + /// + public string Audience { get; init; } = "sign-flow-gen.digitaldata.works"; +} diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index 1d2c3522..33a88b0a 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -11,6 +11,7 @@ using DigitalData.UserManager.DependencyInjection; using EnvelopeGenerator.Application; using DigitalData.Auth.Client; using DigitalData.Core.Abstractions; +using EnvelopeGenerator.GeneratorAPI.Models; var builder = WebApplication.CreateBuilder(args); @@ -90,6 +91,8 @@ builder.Services.AddDbContext(options => options.UseSqlServer(connS builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams")); +var authTokenKeys = config.GetOrDefault(); + // Authentication builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => diff --git a/EnvelopeGenerator.GeneratorAPI/appsettings.json b/EnvelopeGenerator.GeneratorAPI/appsettings.json index d7c6e9bd..c03dbb20 100644 --- a/EnvelopeGenerator.GeneratorAPI/appsettings.json +++ b/EnvelopeGenerator.GeneratorAPI/appsettings.json @@ -30,5 +30,11 @@ } ], "RetryDelay": "00:00:05" + }, + "AuthTokenKeys": { + "Cookie": "AuthToken", + "QueryString": "AuthToken", + "Issuer": "auth.digitaldata.works", + "Audience": "work-flow.digitaldata.works" } } diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index cea3cddf..aef2abb2 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj index 21591d1f..5f47b8bc 100644 --- a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj +++ b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj @@ -19,7 +19,7 @@ - + diff --git a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj index 61e7c13e..cd171c0f 100644 --- a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj +++ b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj @@ -23,7 +23,7 @@ - + diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index bfc6d63c..932642ef 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -2101,7 +2101,7 @@ - + From 2d3987b81e58a334d0ecae8f0359acbbb28bfdc7 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 16:18:31 +0200 Subject: [PATCH 6/9] Add JWT Bearer authentication support - Integrated JWT Bearer authentication for API security. - Replaced previous CookieAuthenticationDefaults with JwtBearerDefaults as the default authentication scheme. - Configured JWT token validation with issuer, audience, and signing key parameters. - Added handling for token retrieval from cookies or query strings when missing in the header. - Updated the authentication configuration to support both Cookie and JWT authentication schemes. - Enhanced security by validating JWT tokens against provided public keys. --- .../EnvelopeGenerator.Application.csproj | 2 +- .../EnvelopeGenerator.Domain.csproj | 2 +- .../EnvelopeGenerator.GeneratorAPI.csproj | 2 +- EnvelopeGenerator.GeneratorAPI/Program.cs | 42 +++++++++++++++++++ .../EnvelopeGenerator.Infrastructure.csproj | 2 +- .../EnvelopeGenerator.Terminal.csproj | 2 +- ...EnvelopeGenerator.Tests.Application.csproj | 2 +- .../EnvelopeGenerator.Web.csproj | 2 +- 8 files changed, 49 insertions(+), 7 deletions(-) diff --git a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj index deaf9710..73ba45fe 100644 --- a/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj +++ b/EnvelopeGenerator.Application/EnvelopeGenerator.Application.csproj @@ -13,7 +13,7 @@ - + diff --git a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj index 60dd3bd2..97b0ca90 100644 --- a/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj +++ b/EnvelopeGenerator.Domain/EnvelopeGenerator.Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj index 30539d93..6e922bad 100644 --- a/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj +++ b/EnvelopeGenerator.GeneratorAPI/EnvelopeGenerator.GeneratorAPI.csproj @@ -25,7 +25,7 @@ - + diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index 33a88b0a..bfdb024b 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -12,6 +12,9 @@ using EnvelopeGenerator.Application; using DigitalData.Auth.Client; using DigitalData.Core.Abstractions; using EnvelopeGenerator.GeneratorAPI.Models; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; +using DigitalData.Core.Abstractions.Security.Extensions; var builder = WebApplication.CreateBuilder(args); @@ -93,6 +96,45 @@ builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams")); var authTokenKeys = config.GetOrDefault(); +builder.Services.AddAuthentication(options => +{ + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}) + .AddJwtBearer(opt => + { + opt.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => + { + var clientParams = deferredProvider.GetOptions(); + var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience); + return new List() { publicKey.SecurityKey }; + }, + ValidateIssuer = true, + ValidIssuer = authTokenKeys.Issuer, + ValidateAudience = true, + ValidAudience = authTokenKeys.Audience, + }; + + opt.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + // if there is no token read related cookie or query string + if (context.Token is null) // if there is no token + { + if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null) + context.Token = cookieToken; + else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken)) + context.Token = queryStrToken; + } + return Task.CompletedTask; + } + }; + }); + // Authentication builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => diff --git a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj index aef2abb2..f93f27c1 100644 --- a/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj +++ b/EnvelopeGenerator.Infrastructure/EnvelopeGenerator.Infrastructure.csproj @@ -7,7 +7,7 @@ - + diff --git a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj index 5f47b8bc..0fea2531 100644 --- a/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj +++ b/EnvelopeGenerator.Terminal/EnvelopeGenerator.Terminal.csproj @@ -19,7 +19,7 @@ - + diff --git a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj index cd171c0f..1c549a9b 100644 --- a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj +++ b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj @@ -23,7 +23,7 @@ - + diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 932642ef..dbbfc909 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -2101,7 +2101,7 @@ - + From a85397a363cade6931d5c7ac1857cc9e7834e502 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 28 Apr 2025 16:49:46 +0200 Subject: [PATCH 7/9] =?UTF-8?q?refactor(auth):=20Refactoring=20der=20Login?= =?UTF-8?q?-Methoden=20f=C3=BCr=20OpenAPI-Kompatibilit=C3=A4t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit – Die Login-Methoden wurden überarbeitet, um NotImplementedException auszulösen und OpenAPI (Swagger) und Skalar zu konfigurieren. – Unnötige using-Anweisungen wurden entfernt, um den Code zu optimieren. --- .../Controllers/AuthController.cs | 307 ++++++++---------- 1 file changed, 129 insertions(+), 178 deletions(-) diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs index 5ce1ce7a..68b4d5c4 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs @@ -5,197 +5,148 @@ using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; -using DigitalData.UserManager.Application.DTOs.Auth; using Microsoft.AspNetCore.Authorization; using EnvelopeGenerator.GeneratorAPI.Models; -namespace EnvelopeGenerator.GeneratorAPI.Controllers +namespace EnvelopeGenerator.GeneratorAPI.Controllers; + +/// +/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus. +/// +[Route("api/[controller]")] +[ApiController] +public partial class AuthController : ControllerBase { + private readonly ILogger _logger; + private readonly IUserService _userService; + private readonly IDirectorySearchService _dirSearchService; + /// - /// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus. + /// Initializes a new instance of the class. /// - [Route("api/[controller]")] - [ApiController] - public partial class AuthController : ControllerBase + /// The logger instance. + /// The user service instance. + /// The directory search service instance. + public AuthController(ILogger logger, IUserService userService, IDirectorySearchService dirSearchService) { - private readonly ILogger _logger; - private readonly IUserService _userService; - private readonly IDirectorySearchService _dirSearchService; - - /// - /// Initializes a new instance of the class. - /// - /// The logger instance. - /// The user service instance. - /// The directory search service instance. - public AuthController(ILogger logger, IUserService userService, IDirectorySearchService dirSearchService) - { - _logger = logger; - _userService = userService; - _dirSearchService = dirSearchService; - } - - /// - /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben. - /// - /// Benutzeranmeldedaten (Benutzername und Passwort). - /// Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet. - /// - /// Gibt eine HTTP 200 oder 401. - /// - /// - /// Sample request: - /// - /// POST /api/auth?cookie=true - /// { - /// "username": "MaxMustermann", - /// "password": "Geheim123!" - /// } - /// - /// POST /api/auth?cookie=true - /// { - /// "id": "1", - /// "password": "Geheim123!" - /// } - /// - /// - /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. - /// Unbefugt. Ungültiger Benutzername oder Passwort. - [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [AllowAnonymous] - [HttpPost] - public async Task Login([FromBody] Login login, [FromQuery] bool cookie = false) - { - try - { - bool isValid = _dirSearchService.ValidateCredentials(login.Username, login.Password); - - if (!isValid) - return Unauthorized(); - - //find the user - var uRes = await _userService.ReadByUsernameAsync(login.Username); - if (!uRes.IsSuccess || uRes.Data is null) - { - return Forbid(); - } - - UserReadDto user = uRes.Data; - - // Create claims - var claims = new List - { - new (ClaimTypes.NameIdentifier, user.Id.ToString()), - new (ClaimTypes.Name, user.Username), - new (ClaimTypes.Surname, user.Name!), - new (ClaimTypes.GivenName, user.Prename!), - new (ClaimTypes.Email, user.Email!), - }; - - // Create claimsIdentity - var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); - - // Create authProperties - var authProperties = new AuthenticationProperties - { - IsPersistent = true, - AllowRefresh = true, - ExpiresUtc = DateTime.Now.AddMinutes(180) - }; + _logger = logger; + _userService = userService; + _dirSearchService = dirSearchService; + } - // Sign in - await HttpContext.SignInAsync( - CookieAuthenticationDefaults.AuthenticationScheme, - new ClaimsPrincipal(claimsIdentity), - authProperties); + /// + /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben. + /// + /// Benutzeranmeldedaten (Benutzername und Passwort). + /// Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet. + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth?cookie=true + /// { + /// "username": "MaxMustermann", + /// "password": "Geheim123!" + /// } + /// + /// POST /api/auth?cookie=true + /// { + /// "id": "1", + /// "password": "Geheim123!" + /// } + /// + /// + /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. + /// Unbefugt. Ungültiger Benutzername oder Passwort. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [AllowAnonymous] + [HttpPost] + public Task Login([FromBody] Login login, [FromQuery] bool cookie = false) + { + // added to configure open API (swagger and scalar) + throw new NotImplementedException(); + } - return Ok(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } - } + /// + /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben. + /// + /// Benutzeranmeldedaten (Benutzername und Passwort). + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth/form + /// { + /// "username": "MaxMustermann", + /// "password": "Geheim123!" + /// } + /// + /// + /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. + /// Unbefugt. Ungültiger Benutzername oder Passwort. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [AllowAnonymous] + [HttpPost] + [Route("form")] + public Task Login([FromForm] Login login) + { + // added to configure open API (swagger and scalar) + throw new NotImplementedException(); + } - /// - /// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben. - /// - /// Benutzeranmeldedaten (Benutzername und Passwort). - /// - /// Gibt eine HTTP 200 oder 401. - /// - /// - /// Sample request: - /// - /// POST /api/auth/form - /// { - /// "username": "MaxMustermann", - /// "password": "Geheim123!" - /// } - /// - /// - /// Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist. - /// Unbefugt. Ungültiger Benutzername oder Passwort. - [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [AllowAnonymous] - [HttpPost] - [Route("form")] - public async Task Login([FromForm] Login login) + /// + /// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie) + /// + /// + /// Gibt eine HTTP 200 oder 401. + /// + /// + /// Sample request: + /// + /// POST /api/auth/logout + /// + /// + /// Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat. + /// Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [Authorize] + [HttpPost("logout")] + public async Task Logout() + { + try { - return await Login(login, true); + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + return Ok(); } - - /// - /// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie) - /// - /// - /// Gibt eine HTTP 200 oder 401. - /// - /// - /// Sample request: - /// - /// POST /api/auth/logout - /// - /// - /// Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat. - /// Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben. - [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [Authorize] - [HttpPost("logout")] - public async Task Logout() + catch (Exception ex) { - try - { - await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - return Ok(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message); - return StatusCode(StatusCodes.Status500InternalServerError); - } + _logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); } - - /// - /// Prüft, ob der Benutzer ein autorisiertes Token hat. - /// - /// Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401 - /// - /// Sample request: - /// - /// GET /api/auth - /// - /// - /// Wenn es einen autorisierten Cookie gibt. - /// Wenn kein Cookie vorhanden ist oder nicht autorisierte. - [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [Authorize] - [HttpGet] - public IActionResult IsAuthenticated() => Ok(); } + + /// + /// Prüft, ob der Benutzer ein autorisiertes Token hat. + /// + /// Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401 + /// + /// Sample request: + /// + /// GET /api/auth + /// + /// + /// Wenn es einen autorisierten Cookie gibt. + /// Wenn kein Cookie vorhanden ist oder nicht autorisierte. + [ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [Authorize] + [HttpGet] + public IActionResult IsAuthenticated() => Ok(); } \ No newline at end of file From c173814b8d736435c8c76b73bf4fe51821d4d74f Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 29 Apr 2025 09:21:05 +0200 Subject: [PATCH 8/9] refactor(AuthController): Login-Methoden aktualisieren, um NotImplementedException zu werfen, nur um Swagger-Dokumentation bereitzustellen --- EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs index 68b4d5c4..a5e8f748 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/AuthController.cs @@ -1,10 +1,8 @@ using DigitalData.Core.Abstractions.Application; using DigitalData.UserManager.Application.Contracts; -using DigitalData.UserManager.Application.DTOs.User; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; -using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using EnvelopeGenerator.GeneratorAPI.Models; From 3d1966a715010c1bbfbf42fcf1b41e6116415eed Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Tue, 29 Apr 2025 09:34:57 +0200 Subject: [PATCH 9/9] feat(Jenkinsfile): Als Beispiel erstellt --- EnvelopeGenerator.GeneratorAPI/Jenkinsfile | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 EnvelopeGenerator.GeneratorAPI/Jenkinsfile diff --git a/EnvelopeGenerator.GeneratorAPI/Jenkinsfile b/EnvelopeGenerator.GeneratorAPI/Jenkinsfile new file mode 100644 index 00000000..3546ad67 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Jenkinsfile @@ -0,0 +1,10 @@ +pipeline { + agent any + stages { + stage('Build') { + steps { + sh 'dotnet build' + } + } + } +}