Enhance AppConfig with JWT settings and update Program.cs for improved authentication handling. Modify README.md to reflect new environment variable structure for configuration.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Dapper;
|
||||
using DexDemoBackend;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -8,10 +9,10 @@ using Microsoft.IdentityModel.Protocols;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Npgsql;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Configure AppConfig using IConfiguration
|
||||
builder.Services.Configure<AppConfig>(builder.Configuration.GetSection("AppConfig"));
|
||||
builder.Services.AddSingleton(sp => sp.GetRequiredService<Microsoft.Extensions.Options.IOptions<AppConfig>>().Value);
|
||||
|
||||
@@ -31,7 +32,6 @@ builder.Services.ConfigureHttpJsonOptions(options =>
|
||||
var app = builder.Build();
|
||||
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
|
||||
|
||||
// Get current config from DI (supports reload)
|
||||
var currentConfig = app.Services.GetRequiredService<AppConfig>();
|
||||
|
||||
app.UseCors(policy =>
|
||||
@@ -44,7 +44,6 @@ app.UseCors(policy =>
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
// Global error handling middleware
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
try
|
||||
@@ -140,6 +139,14 @@ app.Run();
|
||||
|
||||
static void ConfigureJwtAuthentication(IServiceCollection services, AppConfig config)
|
||||
{
|
||||
if (config.InsecureDevMode)
|
||||
{
|
||||
services.AddAuthentication("InsecureDev")
|
||||
.AddScheme<AuthenticationSchemeOptions, InsecureDevAuthenticationHandler>("InsecureDev", _ => { });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
@@ -152,35 +159,33 @@ static void ConfigureJwtAuthentication(IServiceCollection services, AppConfig co
|
||||
ValidateAudience = false,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ClockSkew = OidcConfigConstants.ClockSkew,
|
||||
NameClaimType = OidcConfigConstants.NameClaimType,
|
||||
RoleClaimType = OidcConfigConstants.RoleClaimType
|
||||
ClockSkew = config.ClockSkew,
|
||||
NameClaimType = config.NameClaimType,
|
||||
RoleClaimType = config.RoleClaimType
|
||||
};
|
||||
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
var nameClaim = context.Principal?.FindFirst(OidcConfigConstants.NameClaimType);
|
||||
var emailClaim = context.Principal?.FindFirst(OidcConfigConstants.EmailClaimType);
|
||||
var nameClaim = context.Principal?.FindFirst(config.NameClaimType);
|
||||
var emailClaim = context.Principal?.FindFirst(config.EmailClaimType);
|
||||
|
||||
if (nameClaim == null && emailClaim != null)
|
||||
{
|
||||
var identity = context.Principal?.Identity as ClaimsIdentity;
|
||||
identity?.AddClaim(new Claim(OidcConfigConstants.NameClaimType, emailClaim.Value));
|
||||
identity?.AddClaim(new Claim(config.NameClaimType, emailClaim.Value));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
|
||||
var httpClientHandler = new HttpClientHandler();
|
||||
|
||||
if (config.InsecureDevMode)
|
||||
|
||||
var httpClientHandler = new HttpClientHandler
|
||||
{
|
||||
httpClientHandler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
|
||||
}
|
||||
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
|
||||
var discoveryUrl = $"{config.Issuer}.well-known/openid-configuration";
|
||||
|
||||
options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
|
||||
@@ -224,21 +229,16 @@ static void ValidateConfiguration(AppConfig config)
|
||||
|
||||
static Task<string> GetUserEmail(HttpContext context, AppConfig config)
|
||||
{
|
||||
if (config.InsecureDevMode)
|
||||
{
|
||||
return Task.FromResult(config.InsecureDevEmail!);
|
||||
}
|
||||
|
||||
if (context.User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
var emailClaim = context.User.FindFirst(OidcConfigConstants.EmailClaimType);
|
||||
var emailClaim = context.User.FindFirst(config.EmailClaimType);
|
||||
if (emailClaim != null)
|
||||
{
|
||||
return Task.FromResult(emailClaim.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.Request.Headers.TryGetValue(OidcConfigConstants.AuthRequestEmailHeader, out var emailHeader))
|
||||
if (context.Request.Headers.TryGetValue(config.AuthRequestEmailHeader, out var emailHeader))
|
||||
{
|
||||
return Task.FromResult(emailHeader.ToString());
|
||||
}
|
||||
@@ -271,23 +271,3 @@ record UserIdentityResponse(
|
||||
string? AuthenticationType,
|
||||
List<ClaimResponse> Claims
|
||||
);
|
||||
|
||||
static class OidcConfigConstants
|
||||
{
|
||||
// Default environment variable values
|
||||
public const string DefaultDbHost = "postgres";
|
||||
public const string DefaultDbPort = "5440";
|
||||
public const string DefaultDbName = "dexdemo";
|
||||
public const string DefaultDbUser = "dexdemo";
|
||||
public const string DefaultDbPassword = "dexdemo";
|
||||
public const string DefaultDexIssuer = "https://dex.127.0.0.1.sslip.io/";
|
||||
|
||||
// JWT settings
|
||||
public const string NameClaimType = "name";
|
||||
public const string RoleClaimType = "role";
|
||||
public const string EmailClaimType = "email";
|
||||
public const string AuthRequestEmailHeader = "X-Auth-Request-Email";
|
||||
|
||||
// Time settings
|
||||
public static readonly TimeSpan ClockSkew = TimeSpan.FromMinutes(5);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user