Authorize a request against SAIF roles¶
SaifAuthorizeAttribute.IsAuthorized(HttpActionContext) decides whether the current caller holds at least one of the roles/resources declared on the attribute, delegating the actual decision to ISecurityApiClient.
| Field | Value |
|---|---|
| Operation ID | OP-08 |
| Trigger | Web API authorization-filter pipeline on any decorated controller/action. |
| Inputs | HttpActionContext, constructed Roles string, request-scoped ISecurityApiClient/IEnvironmentService |
| Outputs | bool |
| Primary components | SaifAuthorizeAttribute.IsAuthorized(HttpActionContext) |
| Entry point | src/SAIF.Web.API/SaifAuthorizeAttribute.cs |
Steps¶
- (construction) Roles passed to the constructor are
Trim()-ed and joined with,into the inheritedAuthorizeAttribute.Rolesproperty (BR-WEBAPI-020).forceProductionRoleis stored in_ForceProductionRoleand never read. Enforce.ArgumentNotNull(actionContext, "actionContext")(BR-WEBAPI-014).- Throws when null.
SAIF.Exceptions.Enforceis implemented inSAIF.Framework.Core; its internal steps could not be embedded — the package is not indexed for this run.**- Resolve
ISecurityApiClientandIEnvironmentServicefromactionContext.Request.GetDependencyScope()(BR-WEBAPI-014). - If
ISecurityApiClientis null →throw new MissingDependencyException("ISecurityApiClient")(BR-WEBAPI-014). - Fail-closed; surfaces as a 500 via the pipeline.*
- If
IEnvironmentServiceis null →throw new MissingDependencyException("IEnvironmentService")(BR-WEBAPI-014). - Fail-closed.
- If
!Roles.Any()(the joined role string is empty) → returntrue(BR-WEBAPI-015). - Decorating with no roles authorizes every caller reaching the filter.
- Read
user = environmentService.User.Identity.Name(BR-WEBAPI-016). environmentService.Useris dereferenced without a null check.- If
user.IsNullOrWhiteSpace()→ returnfalse(BR-WEBAPI-016). - Returns
false→ Handle an unauthorized request. - Strip all spaces from
Roles, split on,, and returntrueif any role satisfiessecurityApiClient.IsAuthorized(user, role)(BR-WEBAPI-017). - The
AnyLINQ evaluation short-circuits on the first success; up to N remote calls otherwise.* ISecurityApiClient.IsAuthorized(user, role)is implemented inSAIF.Framework.Core; its internal steps could not be embedded — the package is not indexed for this run.**- A
falseresult also flows to Handle an unauthorized request.
Process flow¶
flowchart TD
subgraph MainFlow["Authorization decision<br>path"]
Start(["Authorization filter<br>pipeline"]) --> NullCheck["Enforce.ArgumentNotNull(<br>actionContext)"]
NullCheck --> Resolve["Resolve<br>ISecurityApiClient /<br>IEnvironmentService"]
Resolve --> SecNull{ISecurityApiClient null?}
SecNull -->|No| EnvNull{"IEnvironmentService<br>null?"}
EnvNull -->|No| RolesEmpty{"Roles empty?"}
RolesEmpty -->|No| ReadUser["user =<br>environmentService.User.<br>Identity.Name"]
ReadUser --> UserEmpty{"user null/whitespace?"}
UserEmpty -->|No| AnyRole["Any role:<br>securityApiClient.<br>IsAuthorized(user,<br>role)?"]
end
SecNull -->|Yes| ThrowSec["throw<br>MissingDependency<br>Exception"]
EnvNull -->|Yes| ThrowEnv["throw<br>MissingDependency<br>Exception"]
RolesEmpty -->|Yes| AllowAll["return true"]
UserEmpty -->|Yes| Deny["return false"]
AnyRole -->|True| Allow[return true]
AnyRole -->|False| Deny2["return false"]
Failure and edge-case behavior¶
- A missing
ISecurityApiClientorIEnvironmentServicethrowsMissingDependencyException, which surfaces as an unhandled server error (not a 401/403).* environmentService.Useris dereferenced without a null guard; an environment service that returns anullUserwould raiseNullReferenceException.
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
Related documentation¶
Sources¶
src/SAIF.Web.API/SaifAuthorizeAttribute.cs