Skip to content

Harden production JWT wiring and Swagger diagnostics in ASP.NET Core backend#46

Merged
mukund58 merged 2 commits into
masterfrom
copilot/follow-this
Apr 26, 2026
Merged

Harden production JWT wiring and Swagger diagnostics in ASP.NET Core backend#46
mukund58 merged 2 commits into
masterfrom
copilot/follow-this

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 26, 2026

Production failures were caused by inconsistent JWT configuration paths between token generation and token validation, plus insufficient diagnostics around Swagger/auth exceptions. This could produce invalid tokens, intermittent login failures, and 401s across protected endpoints.

  • JWT config unification (single source of truth)

    • Added strongly-typed JwtSettingsOptions bound from JwtSettings.
    • Removed divergent JWT fallbacks in auth token generation.
    • Enforced startup validation for required JWT fields (secret/issuer/audience/expiration) with byte-length check for secret.
  • Token generation/validation alignment

    • Updated AuthService to generate tokens exclusively from IOptions<JwtSettingsOptions>.
    • Updated JWT bearer setup to validate issuer and audience using the same config values used at issuance.
    • Kept role/name claim mapping explicit to avoid claim interpretation drift.
  • Production-safe diagnostics

    • Added startup logs that report config presence/shape without exposing secret values.
    • Added JWT event logging (authentication failed, challenge, forbidden, token validated) with safe structured messages.
    • Updated global exception middleware to emit a dedicated Swagger-generation error log path.
  • Swagger resilience

    • Added stable schema ID generation (FullName) to reduce schema naming collisions during OpenAPI generation.
  • Test updates

    • Adjusted AuthService tests to use typed JWT options and logger dependencies.
builder.Services.Configure<JwtSettingsOptions>(
    builder.Configuration.GetSection(JwtSettingsOptions.SectionName));

options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Secret)),
    ValidateIssuer = true,
    ValidIssuer = jwtSettings.Issuer,
    ValidateAudience = true,
    ValidAudience = jwtSettings.Audience,
    ValidateLifetime = true,
    ClockSkew = TimeSpan.Zero
};

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
taskflow-dotnet Ready Ready Preview, Comment Apr 26, 2026 7:46am

Copy link
Copy Markdown
Owner

@mukund58 mukund58 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@mukund58 mukund58 marked this pull request as ready for review April 26, 2026 07:47
Copilot AI review requested due to automatic review settings April 26, 2026 07:47
@mukund58 mukund58 merged commit a8a6426 into master Apr 26, 2026
5 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns JWT token issuance and validation configuration to prevent production auth failures, and adds safer startup/Swagger/auth diagnostics for troubleshooting.

Changes:

  • Introduces strongly-typed JwtSettingsOptions with startup validation and binds it from JwtSettings.
  • Updates JWT generation (AuthService) and JWT bearer validation (Program.cs) to use consistent issuer/audience/secret/expiry values.
  • Improves diagnostics: Swagger schema IDs, JWT bearer event logging, and Swagger-specific exception logging.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Backend/Services/Implementations/AuthService.cs Switches token generation to typed JWT settings + adds token issuance logging.
Backend/Program.cs Binds/validates JWT settings at startup; tightens bearer validation; adds JWT event + startup diagnostics; stabilizes Swagger schema IDs.
Backend/Middleware/GlobalExceptionMiddleware.cs Adds dedicated logging path for Swagger generation exceptions.
Backend/Data/JwtSettingsOptions.cs Adds typed JWT settings model and validation helper.
Backend.Tests/Services/AuthServiceTests.cs Updates tests to construct AuthService with typed options + logger.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +120 to +125
_logger.LogInformation(
"Generated JWT token for UserId={UserId} with issuer={Issuer}, audience={Audience}, expirationHours={ExpirationHours}",
user.Id,
_jwtSettings.Issuer,
_jwtSettings.Audience,
_jwtSettings.ExpirationHours);
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The token-generation log is emitted at Information level and includes UserId plus auth configuration details. Consider reducing this to Debug (or sampling) and/or removing UserId to avoid generating high-sensitivity audit data/PII in general application logs.

Suggested change
_logger.LogInformation(
"Generated JWT token for UserId={UserId} with issuer={Issuer}, audience={Audience}, expirationHours={ExpirationHours}",
user.Id,
_jwtSettings.Issuer,
_jwtSettings.Audience,
_jwtSettings.ExpirationHours);
_logger.LogDebug("Generated JWT token.");

Copilot uses AI. Check for mistakes.
Comment thread Backend/Program.cs
Comment on lines +161 to +162
context.Exception,
"JWT authentication failed.");
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OnAuthenticationFailed logs the full exception object. IdentityModel exceptions can include detailed failure data in the exception message/stack trace; for auth failures this can be noisy and may risk leaking sensitive request details into logs. Prefer logging a sanitized message (e.g., exception type / error code) without attaching the full exception, and consider lowering the level for expected failures.

Suggested change
context.Exception,
"JWT authentication failed.");
"JWT authentication failed. ExceptionType={ExceptionType}",
context.Exception.GetType().Name);

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +19
public IEnumerable<string> Validate()
{
if (string.IsNullOrWhiteSpace(Secret))
yield return $"{SectionName}:Secret is required";
else if (Encoding.UTF8.GetByteCount(Secret) < 32)
yield return $"{SectionName}:Secret must be at least 32 bytes when UTF-8 encoded";
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JwtSettingsOptions.Validate() introduces important startup-gating behavior (required fields + secret length), but there are no unit tests covering the expected error cases. Adding focused tests for this method would help prevent regressions in configuration validation rules.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants