Skip to content

Evaluate a role requirement

Evaluates one RoleRequirement by extracting both candidate identities from the current request and delegating the actual authorization decision to NtlmApiAuthorizationService.

Field Value
Operation ID OP-06
Trigger ASP.NET Core authorization for an endpoint whose policy came from Build named role policies, invoked via the framework PassThroughAuthorizationHandler
Inputs AuthorizationHandlerContext, RoleRequirement (self)
Outputs context.Succeed(requirement) or context.Fail()
Primary components RoleRequirement.HandleRequirementAsync
Entry point src/SAIF.NetCore.NtlmApiAuth/src/SAIF.NetCore.NtlmApiAuth/Authorization/RoleRequirement.cs

Steps

  1. Compute requestUser = context.User.Identity.Name with the domain removed via DomainlessUser (null-safe). (BR-NTLM-004, BR-NTLM-011)
  2. Compute onBehalfOfUser = context.OnBehalfOfUser() — the first OnBehalfOfUser claim value, or string.Empty if absent. (BR-NTLM-001)
  3. Delegate to Dual-identity authorization — INtlmApiAuthorizationService.IsAuthorized(requestUser, onBehalfOfUser, _role) — using this instance's own _role, which is not necessarily the role carried by the requirement argument (because RoleRequirement is a self-handling requirement whose handler cross-evaluates every requirement in the context). The delegated logic, embedded here for reference:
  4. If requestUser is blank, the call returns false immediately with no remote call.
  5. Otherwise it checks requestUser against _role via the embedded AuthService call; if that check fails, the overall result is false and onBehalfOfUser is never evaluated.
  6. If the caller check succeeds and onBehalfOfUser is blank, the result is the caller check alone (true).
  7. If the caller check succeeds and onBehalfOfUser is present, a second check runs onBehalfOfUser against _role, and both identities must pass for the overall result to be true.
  8. See Dual-identity authorization for the full embedded AuthService rewrite/error/wire-format behavior behind each check.

Origin: Step 3 is implemented in Dual-identity authorization (SAIF.NetCore.NtlmApiAuth) and executed on behalf of this operation. 4. If the result is true, call context.Succeed(requirement); otherwise call context.Fail(), which fails the entire authorization regardless of any other requirement's success. (BR-NTLM-007) - On failure (exception): a SecurityClientException raised deep inside the delegated AuthService call (see step 3) propagates out of this handler uncaught — the resulting HTTP response is a function of the host's own error handling and is inferred to be a server error rather than an independently-verified 403.* (BR-NTLM-008)

Process flow

flowchart TD
    Start([Authorization evaluation]) --> S1[Compute domainless request user]
    S1 --> S2[Read OnBehalfOfUser claim]
    S2 --> S3[Call NtlmApiAuthorizationService.IsAuthorized]
    S3 --> D{Result}
    D -->|true| Succeed([context.Succeed])
    D -->|false| Fail([context.Fail])
    D -->|exception| Err(["Exception propagates to the caller,<br>uncaught by this handler"])

Failure and edge-case behavior

  • With N roles in a single policy, each RoleRequirement's self-handling behavior evaluates its own role against every requirement in the context, so SecurityAPI can be called up to 2·N² times per request*.

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • src/SAIF.NetCore.NtlmApiAuth/src/SAIF.NetCore.NtlmApiAuth/Authorization/RoleRequirement.cs