JWT controller claim helpers¶
This operation provides two claim-derivation helpers on JwtControllerBase: deriving a display username from the nameidentifier-type claim, and parsing the authentication time from the auth_time claim.
| Field | Value |
|---|---|
| Operation ID | OP-22 |
| Trigger | A controller derived from JwtControllerBase calls GetUsernameFromClaim() or GetAuthTimeFromClaim(). |
| Inputs | The current user's ClaimsPrincipal (via HttpContext.User). |
| Outputs | A derived username string, or a parsed DateTime authentication time. |
| Primary components | JwtControllerBase.GetUsernameFromClaim, .GetAuthTimeFromClaim |
| Entry point | src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/JwtControllerBase.cs (L14–40) |
Steps¶
GetUsernameFromClaim: find the first claim whose type contains"nameidentifier", split its value on@, take index[0], upper-case the result (BR-SE-27)- On exception during parsing: returns
"Unknown". - If the claim is missing: returns
null. GetAuthTimeFromClaim: find theauth_timeclaim and, only iflong.TryParsesucceeds on its value, parse it as Unix seconds since epoch viaDateTimeOffset.FromUnixTimeSeconds(unixTimestamp).UtcDateTime(BR-SE-27)- If the claim is missing or its value is not a parseable
long: returnsDateTime.MinValuewithout throwing. - If the value parses as a
longbut is outside the rangeDateTimeOffset.FromUnixTimeSecondssupports: the method has notry/catch, soArgumentOutOfRangeExceptionpropagates uncaught to the caller — this is a distinct third outcome from the two above.
Process flow¶
This diagram shows the per-call branching inside each helper on a single invocation of GetUsernameFromClaim/GetAuthTimeFromClaim, not a combined or sequential call to both.
flowchart TD
Start([GetUsernameFromClaim / GetAuthTimeFromClaim called]) --> S1{Which helper?}
S1 -->|Username| S2{nameidentifier claim present?}
S2 -->|No| EndNull([Return null])
S2 -->|Yes| S3{Parsing succeeds?}
S3 -->|Yes| EndName([Return upper-cased local part])
S3 -->|No| EndUnknown(["Return 'Unknown'"])
S1 -->|Auth time| S4{auth_time claim present and long.TryParse succeeds?}
S4 -->|No| EndMin([Return DateTime.MinValue])
S4 -->|Yes| S5{"Value in FromUnixTimeSeconds range?"}
S5 -->|Yes| EndTime([Return parsed DateTime])
S5 -->|No| EndThrow(["ArgumentOutOfRangeException propagates uncaught"])
Failure and edge-case behavior¶
- Any exception while parsing the username claim yields
"Unknown"; a missing claim yieldsnull(these are distinct outcomes). - A missing or non-numeric
auth_timeclaim yieldsDateTime.MinValuerather than throwing. - A numeric
auth_timeclaim value outside the rangeDateTimeOffset.FromUnixTimeSecondssupports throwsArgumentOutOfRangeException, uncaught, fromGetAuthTimeFromClaim— this method has notry/catcharound the conversion, unlikeGetUsernameFromClaim.
Related documentation¶
Sources¶
src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/JwtControllerBase.cs