diff --git a/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/ReceiverClaimExtensions.cs b/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/ReceiverClaimExtensions.cs
new file mode 100644
index 00000000..d851c1de
--- /dev/null
+++ b/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/ReceiverClaimExtensions.cs
@@ -0,0 +1,96 @@
+using DigitalData.Auth.Claims;
+using Microsoft.IdentityModel.JsonWebTokens;
+using System.Security.Claims;
+
+namespace EnvelopeGenerator.API.Extensions;
+
+///
+/// Provides helper methods for working with envelope-specific authentication claims.
+///
+public static class ReceiverClaimExtensions
+{
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static string GetRequiredClaimValue(this ClaimsPrincipal user, string claimType)
+ {
+ var value = user.FindFirstValue(claimType);
+ if (value is not null)
+ {
+ return value;
+ }
+
+ var identity = user.Identity;
+ var principalName = identity?.Name ?? "(anonymous)";
+ var authType = identity?.AuthenticationType ?? "(none)";
+ var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
+ var message = $"Required claim '{claimType}' is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
+ throw new InvalidOperationException(message);
+ }
+
+ private static string GetRequiredClaimValue(this ClaimsPrincipal user, params string[] claimTypes)
+ {
+ foreach (var claimType in claimTypes.Where(t => !string.IsNullOrWhiteSpace(t)).Distinct())
+ {
+ var value = user.FindFirstValue(claimType);
+ if (!string.IsNullOrWhiteSpace(value))
+ return value;
+ }
+
+ var identity = user.Identity;
+ var principalName = identity?.Name ?? "(anonymous)";
+ var authType = identity?.AuthenticationType ?? "(none)";
+ var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
+ var message = $"Required claim(s) '{string.Join("', '", claimTypes)}' are missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
+ throw new InvalidOperationException(message);
+ }
+
+ ///
+ /// Gets the authenticated envelope UUID from the claims.
+ ///
+ public static string EnvelopeUuid(this ClaimsPrincipal user)
+ => user.GetRequiredClaimValue(EnvelopeClaimNames.EnvelopeUuid);
+
+ ///
+ /// Gets the authenticated receiver signature from the claims.
+ ///
+ public static string ReceiverSignature(this ClaimsPrincipal user)
+ => user.GetRequiredClaimValue(EnvelopeClaimNames.ReceiverSignature);
+
+ ///
+ /// Gets the authenticated receiver email address from the claims.
+ ///
+ public static string ReceiverMail(this ClaimsPrincipal user)
+ => user.GetRequiredClaimValue(JwtRegisteredClaimNames.Email);
+
+ ///
+ /// Gets the authenticated envelope identifier from the claims.
+ ///
+ public static int EnvelopeId(this ClaimsPrincipal user)
+ {
+ var envIdStr = user.GetRequiredClaimValue(EnvelopeClaimNames.EnvelopeId);
+ if (int.TryParse(envIdStr, out var envId))
+ return envId;
+ else
+ throw new InvalidOperationException($"Claim '{EnvelopeClaimNames.EnvelopeId}' is not a valid integer.");
+ }
+
+ ///
+ /// Gets the authenticated receiver identifier from the claims.
+ ///
+ ///
+ ///
+ ///
+ public static int ReceiverId(this ClaimsPrincipal user)
+ {
+ var rcvIdStr = user.GetRequiredClaimValue(EnvelopeClaimNames.ReceiverId);
+ if (int.TryParse(rcvIdStr, out var rcvId))
+ return rcvId;
+ else
+ throw new InvalidOperationException($"Claim '{EnvelopeClaimNames.ReceiverId}' is not a valid integer.");
+ }
+}
\ No newline at end of file
diff --git a/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/SenderClaimExtensions.cs b/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/SenderClaimExtensions.cs
new file mode 100644
index 00000000..262968ed
--- /dev/null
+++ b/EnvelopeGenerator.WebUI/EnvelopeGenerator.WebUI/Extensions/SenderClaimExtensions.cs
@@ -0,0 +1,95 @@
+using System.Security.Claims;
+
+namespace EnvelopeGenerator.API.Extensions
+{
+ ///
+ /// Provides extension methods for extracting user information from a .
+ ///
+ public static class SenderClaimExtensions
+ {
+ private static string GetRequiredClaimOfSender(this ClaimsPrincipal user, string claimType)
+ {
+ var value = user.FindFirstValue(claimType);
+ if (value is not null)
+ {
+ return value;
+ }
+
+ var identity = user.Identity;
+ var principalName = identity?.Name ?? "(anonymous)";
+ var authType = identity?.AuthenticationType ?? "(none)";
+ var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
+ var message = $"Required claim '{claimType}' is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
+ throw new InvalidOperationException(message);
+ }
+
+ private static string GetRequiredClaimOfSender(this ClaimsPrincipal user, params string[] claimTypes)
+ {
+ string? value = null;
+
+ foreach (var claimType in claimTypes)
+ {
+ value = user.FindFirstValue(claimType);
+ if (value is not null)
+ return value;
+ }
+
+ var identity = user.Identity;
+ var principalName = identity?.Name ?? "(anonymous)";
+ var authType = identity?.AuthenticationType ?? "(none)";
+ var availableClaims = string.Join(", ", user.Claims.Select(c => $"{c.Type}={c.Value}"));
+ var message = $"Required claim among [{string.Join(", ", claimTypes)}] is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
+ throw new InvalidOperationException(message);
+ }
+
+ ///
+ /// Retrieves the user's ID from the claims. Throws an exception if the ID is missing or invalid.
+ ///
+ /// The representing the user.
+ /// The user's ID as an integer.
+ /// Thrown if the user ID claim is missing or invalid.
+ public static int GetId(this ClaimsPrincipal user)
+ {
+ var idValue = user.GetRequiredClaimOfSender(ClaimTypes.NameIdentifier, "sub");
+
+ 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;
+ }
+
+ ///
+ /// Retrieves the username from the claims.
+ ///
+ /// The representing the user.
+ /// The username as a string.
+ public static string GetUsername(this ClaimsPrincipal user)
+ => user.GetRequiredClaimOfSender(ClaimTypes.Name);
+
+ ///
+ /// Retrieves the user's surname (last name) from the claims.
+ ///
+ /// The representing the user.
+ /// The surname as a string.
+ public static string GetName(this ClaimsPrincipal user)
+ => user.GetRequiredClaimOfSender(ClaimTypes.Surname);
+
+ ///
+ /// Retrieves the user's given name (first name) from the claims.
+ ///
+ /// The representing the user.
+ /// The given name as a string.
+ public static string GetPrename(this ClaimsPrincipal user)
+ => user.GetRequiredClaimOfSender(ClaimTypes.GivenName);
+
+ ///
+ /// Retrieves the user's email address from the claims.
+ ///
+ /// The representing the user.
+ /// The email address as a string.
+ public static string GetEmail(this ClaimsPrincipal user)
+ => user.GetRequiredClaimOfSender(ClaimTypes.Email);
+ }
+}
\ No newline at end of file