Refactor claim access to enforce required user claims
Replaced nullable claim accessors with strict versions that throw exceptions if required claims are missing or invalid. Updated controller logic to use new methods and removed fallback/error handling for missing claims, ensuring stricter claim validation throughout the codebase.
This commit is contained in:
@@ -66,16 +66,7 @@ public class EnvelopeReceiverController : ControllerBase
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetEnvelopeReceiver([FromQuery] ReadEnvelopeReceiverQuery envelopeReceiver)
|
||||
{
|
||||
var username = User.GetUsernameOrDefault();
|
||||
|
||||
if (username is null)
|
||||
{
|
||||
_logger.LogError(@"Envelope Receiver dto cannot be sent because username claim is null. Potential authentication and authorization error. The value of other claims are [id: {id}], [username: {username}], [name: {name}], [prename: {prename}], [email: {email}].",
|
||||
User.GetId(), User.GetUsernameOrDefault(), User.GetNameOrDefault(), User.GetPrenameOrDefault(), User.GetEmailOrDefault());
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
|
||||
envelopeReceiver = envelopeReceiver with { Username = username };
|
||||
envelopeReceiver = envelopeReceiver with { Username = User.GetUsername() };
|
||||
|
||||
var result = await _mediator.Send(envelopeReceiver);
|
||||
|
||||
|
||||
@@ -24,15 +24,6 @@ namespace EnvelopeGenerator.API.Extensions
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the user's ID from the claims. Returns null if the ID is not found or invalid.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The user's ID as an integer, or null if not found or invalid.</returns>
|
||||
public static int? GetIdOrDefault(this ClaimsPrincipal user)
|
||||
=> int.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier) ?? user.FindFirstValue("sub"), out int result)
|
||||
? result : null;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's ID from the claims. Throws an exception if the ID is missing or invalid.
|
||||
/// </summary>
|
||||
@@ -40,39 +31,48 @@ namespace EnvelopeGenerator.API.Extensions
|
||||
/// <returns>The user's ID as an integer.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the user ID claim is missing or invalid.</exception>
|
||||
public static int GetId(this ClaimsPrincipal user)
|
||||
=> user.GetIdOrDefault()
|
||||
?? throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
|
||||
{
|
||||
var idValue = user.FindFirstValue(ClaimTypes.NameIdentifier) ?? user.FindFirstValue("sub");
|
||||
idValue ??= user.GetRequiredClaimOfSender(ClaimTypes.NameIdentifier);
|
||||
|
||||
if (!int.TryParse(idValue, out var result))
|
||||
{
|
||||
throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the username from the claims, if available.
|
||||
/// Retrieves the username from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The username as a string, or null if not found.</returns>
|
||||
public static string? GetUsernameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Name)?.Value;
|
||||
/// <returns>The username as a string.</returns>
|
||||
public static string GetUsername(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's surname (last name) from the claims, if available.
|
||||
/// Retrieves the user's surname (last name) from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The surname as a string, or null if not found.</returns>
|
||||
public static string? GetNameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Surname)?.Value;
|
||||
/// <returns>The surname as a string.</returns>
|
||||
public static string GetName(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Surname);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's given name (first name) from the claims, if available.
|
||||
/// Retrieves the user's given name (first name) from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The given name as a string, or null if not found.</returns>
|
||||
public static string? GetPrenameOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.GivenName)?.Value;
|
||||
/// <returns>The given name as a string.</returns>
|
||||
public static string GetPrename(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.GivenName);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the user's email address from the claims, if available.
|
||||
/// Retrieves the user's email address from the claims.
|
||||
/// </summary>
|
||||
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
|
||||
/// <returns>The email address as a string, or null if not found.</returns>
|
||||
public static string? GetEmailOrDefault(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Email)?.Value;
|
||||
/// <returns>The email address as a string.</returns>
|
||||
public static string GetEmail(this ClaimsPrincipal user)
|
||||
=> user.GetRequiredClaimOfSender(ClaimTypes.Email);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user