refactor: IssuerSigningKeyResolver wurde aktualisiert, um die Konfiguration über serviceProvider anstelle eines separaten öffentlichen Schlüssels zu ermöglichen.

This commit is contained in:
Developer 02
2025-03-11 16:22:54 +01:00
parent d5b1ee41a0
commit f7eaa0f7de
6 changed files with 45 additions and 16 deletions

View File

@@ -20,5 +20,5 @@ public class PlaceholderAuthController : ControllerBase
[HttpGet("check")] [HttpGet("check")]
[Authorize] [Authorize]
public IActionResult Check() => throw new NotImplementedException(); public IActionResult Check() => Ok();
} }

View File

@@ -0,0 +1,18 @@
namespace WorkFlow.API;
public class LazyServiceProvider : IServiceProvider
{
private Lazy<IServiceProvider>? _serviceProvider;
public Func<IServiceProvider> Factory
{
set => _serviceProvider = new(value);
}
public object? GetService(Type serviceType)
{
if (_serviceProvider is null)
throw new InvalidOperationException("GetService cannot be called before _serviceProvider is set.");
return _serviceProvider.Value.GetService(serviceType);
}
}

View File

@@ -5,4 +5,8 @@ public class AuthTokenKeys
public string Cookie { get; init; } = "AuthToken"; public string Cookie { get; init; } = "AuthToken";
public string QueryString { get; init; } = "AuthToken"; public string QueryString { get; init; } = "AuthToken";
public string Issuer { get; init; } = "auth.digitaldata.works";
public string Audience { get; init; } = "work-flow.digitaldata.works";
} }

View File

@@ -2,7 +2,6 @@ using WorkFlow.Application;
using DigitalData.UserManager.Application; using DigitalData.UserManager.Application;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using WorkFlow.Infrastructure; using WorkFlow.Infrastructure;
using Microsoft.AspNetCore.Authentication.Cookies;
using DigitalData.Core.API; using DigitalData.Core.API;
using DigitalData.Core.Application; using DigitalData.Core.Application;
using DigitalData.UserManager.Application.DTOs.User; using DigitalData.UserManager.Application.DTOs.User;
@@ -15,6 +14,9 @@ using WorkFlow.API.Filters;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using DigitalData.Auth.Client; using DigitalData.Auth.Client;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using WorkFlow.API;
using Microsoft.Extensions.Options;
using DigitalData.Core.Abstractions.Security;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Logging initialized."); logger.Info("Logging initialized.");
@@ -48,10 +50,9 @@ try
else else
throw new("The API Key Authorization configuration is not available in the app settings, even though the app is not in development or DiP mode and API Key Authorization is not disabled."); throw new("The API Key Authorization configuration is not available in the app settings, even though the app is not in development or DiP mode and API Key Authorization is not disabled.");
// Created separately from AuthClientParams (added via options) for use in Jwt Bearer configuration var lazyProvider = new LazyServiceProvider();
var authPublicKey = config.GetSection("AuthPublicKey").Get<ClientPublicKey>() ?? throw new InvalidOperationException("The AuthPublicKey configuration is missing or invalid.");
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"), opt => opt.PublicKeys.Add(authPublicKey)); builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
builder.Services.AddControllers(); builder.Services.AddControllers();
@@ -69,12 +70,14 @@ try
ValidateIssuerSigningKey = true, ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
{ {
return [authPublicKey.SecurityKey]; var clientParams = lazyProvider.GetRequiredService<IOptions<ClientParams>>()?.Value;
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
return [publicKey.SecurityKey];
}, },
ValidateIssuer = true, ValidateIssuer = true,
ValidIssuer = authPublicKey.Issuer, ValidIssuer = authTokenKeys.Issuer,
ValidateAudience = true, ValidateAudience = true,
ValidAudience = authPublicKey.Audience, ValidAudience = authTokenKeys.Audience,
}; };
opt.Events = new JwtBearerEvents opt.Events = new JwtBearerEvents
@@ -130,6 +133,8 @@ try
var app = builder.Build(); var app = builder.Build();
lazyProvider.Factory = () => app.Services;
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.IsDevOrDiP() && app.Configuration.GetValue<bool>("EnableSwagger")) if (app.IsDevOrDiP() && app.Configuration.GetValue<bool>("EnableSwagger"))
{ {

View File

@@ -12,7 +12,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DigitalData.Auth.Client" Version="1.1.5" /> <PackageReference Include="DigitalData.Auth.Client" Version="1.2.1.1" />
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<PackageReference Include="NLog" Version="5.3.4" /> <PackageReference Include="NLog" Version="5.3.4" />

View File

@@ -78,12 +78,14 @@
} }
}, },
"AuthClientParams": { "AuthClientParams": {
"Url": "https://localhost:7192", "Url": "https://localhost:7192/auth-hub",
"PublicKeys": [] "PublicKeys": [
}, {
"AuthPublicKey": { "Issuer": "auth.digitaldata.works",
"Issuer": "auth.digitaldata.works", "Audience": "work-flow.digitaldata.works",
"Audience": "work-flow.digitaldata.works", "Content": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QCd7dH/xOUITFZbitMa/xnh8a0LyL6ZBvSRAwkI9ceplTRSHJXoM1oB+xtjWE1kOuHVLe941Tm03szS4+/rHIm0Ejva/KKlv7sPFAHE/pWuoPS303vOHgI4HAFcuwywA8CghUWzaaK5LU/Hl8srWwxBHv5hKIUjJFJygeAIENvFOZ1gFbB3MPEC99PiPOwAmfl4tMQUmSsFyspl/RWVi7bTv26ZE+m3KPcWppmvmYjXlSitxRaySxnfFvpca/qWfd/uUUg2KWKtpAwWVkqr0qD9v3TyKSgHoGDsrFpwSx8qufUJSinmZ1u/0iKl6TXeHubYS4C4SUSVjOWXymI2ZQIDAQAB-----END PUBLIC KEY-----"
"Content": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QCd7dH/xOUITFZbitMa/xnh8a0LyL6ZBvSRAwkI9ceplTRSHJXoM1oB+xtjWE1kOuHVLe941Tm03szS4+/rHIm0Ejva/KKlv7sPFAHE/pWuoPS303vOHgI4HAFcuwywA8CghUWzaaK5LU/Hl8srWwxBHv5hKIUjJFJygeAIENvFOZ1gFbB3MPEC99PiPOwAmfl4tMQUmSsFyspl/RWVi7bTv26ZE+m3KPcWppmvmYjXlSitxRaySxnfFvpca/qWfd/uUUg2KWKtpAwWVkqr0qD9v3TyKSgHoGDsrFpwSx8qufUJSinmZ1u/0iKl6TXeHubYS4C4SUSVjOWXymI2ZQIDAQAB-----END PUBLIC KEY-----" }
],
"RetryDelay": "00:00:05"
} }
} }