Fix OIDC issuer handling behind internal HTTP proxies

This commit is contained in:
Warren Chen 2026-04-02 02:43:50 +09:00
parent 293303c989
commit 693c6d262a

View File

@ -14,6 +14,9 @@ EnvLoader.LoadDotEnvIfDevelopment();
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var pathBase = NormalizePathBase(builder.Configuration["PathBase"]); var pathBase = NormalizePathBase(builder.Configuration["PathBase"]);
var issuer = builder.Configuration["Auth:Issuer"];
var issuerUri = ParseAbsoluteUriOrThrow(issuer, "Auth:Issuer");
var allowInsecureHttp = builder.Configuration.GetValue("Auth:AllowInsecureHttp", false);
builder.Services.AddDbContext<MemberCenterDbContext>(options => builder.Services.AddDbContext<MemberCenterDbContext>(options =>
{ {
@ -58,14 +61,8 @@ builder.Services.AddOpenIddict()
WithPathBase(pathBase, "/auth/login"), WithPathBase(pathBase, "/auth/login"),
WithPathBase(pathBase, "/auth/refresh")); WithPathBase(pathBase, "/auth/refresh"));
options.SetLogoutEndpointUris(WithPathBase(pathBase, "/auth/logout")); options.SetLogoutEndpointUris(WithPathBase(pathBase, "/auth/logout"));
var issuer = builder.Configuration["Auth:Issuer"]; if (issuerUri is not null)
if (!string.IsNullOrWhiteSpace(issuer))
{ {
if (!Uri.TryCreate(issuer, UriKind.Absolute, out var issuerUri))
{
throw new InvalidOperationException("Auth:Issuer must be an absolute URI.");
}
options.SetIssuer(issuerUri); options.SetIssuer(issuerUri);
} }
@ -98,9 +95,9 @@ builder.Services.AddOpenIddict()
.EnableLogoutEndpointPassthrough() .EnableLogoutEndpointPassthrough()
.EnableStatusCodePagesIntegration(); .EnableStatusCodePagesIntegration();
if (builder.Environment.IsDevelopment()) if (builder.Environment.IsDevelopment() || allowInsecureHttp)
{ {
// TEST/LOCAL ONLY: allow HTTP for local Docker integration testing. // Allows OIDC/OAuth endpoints to operate behind non-HTTPS internal networks/proxies.
aspNetCore.DisableTransportSecurityRequirement(); aspNetCore.DisableTransportSecurityRequirement();
} }
}) })
@ -139,6 +136,17 @@ if (!string.IsNullOrWhiteSpace(pathBase))
app.UsePathBase(pathBase); app.UsePathBase(pathBase);
} }
app.Use(async (context, next) =>
{
if (issuerUri is not null && IsOpenIddictRequest(context.Request.Path))
{
context.Request.Scheme = issuerUri.Scheme;
context.Request.Host = HostString.FromUriComponent(issuerUri);
}
await next();
});
app.UseRouting(); app.UseRouting();
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
@ -165,3 +173,25 @@ static string WithPathBase(string? pathBase, string relativePath)
? normalizedRelativePath ? normalizedRelativePath
: $"{pathBase}{normalizedRelativePath}"; : $"{pathBase}{normalizedRelativePath}";
} }
static Uri? ParseAbsoluteUriOrThrow(string? uri, string configKey)
{
if (string.IsNullOrWhiteSpace(uri))
{
return null;
}
if (!Uri.TryCreate(uri, UriKind.Absolute, out var parsed))
{
throw new InvalidOperationException($"{configKey} must be an absolute URI.");
}
return parsed;
}
static bool IsOpenIddictRequest(PathString path)
{
return path.StartsWithSegments("/.well-known", StringComparison.OrdinalIgnoreCase)
|| path.StartsWithSegments("/oauth", StringComparison.OrdinalIgnoreCase)
|| path.StartsWithSegments("/auth", StringComparison.OrdinalIgnoreCase);
}