Handle an unauthorized request¶
SaifAuthorizeAttribute.HandleUnauthorizedRequest(HttpActionContext) logs the denial (when the user is known) and answers the caller with a structured 401.
| Field | Value |
|---|---|
| Operation ID | OP-09 |
| Trigger | Invoked by AuthorizeAttribute when Authorize a request against SAIF roles returns false. |
| Inputs | HttpActionContext |
| Outputs | sets actionContext.Response to 401 |
| Primary components | SaifAuthorizeAttribute.HandleUnauthorizedRequest(HttpActionContext) |
| Entry point | src/SAIF.Web.API/SaifAuthorizeAttribute.cs |
Steps¶
Enforce.ArgumentNotNull(actionContext, "actionContext")(BR-WEBAPI-014).SAIF.Exceptions.Enforceis implemented inSAIF.Framework.Core; its internal steps could not be embedded — the package is not indexed for this run.**- Resolve
ILogServiceandIEnvironmentServicefrom the request dependency scope;Enforce.ArgumentNotNulleach (BR-WEBAPI-014). - Unlike Post-process an API response, logging is mandatory here — a missing
ILogServicethrows. user = environmentService.UserId().SAIF.Common.Extensions.UserId()is implemented inSAIF.Framework.Core; its internal steps could not be embedded — the package is not indexed for this run.**- If
!user.IsNullOrEmpty(), calllogService.LogException(applicationName, controllerAndActionName, state: GetContext(actionContext, environmentService), exception: new SecurityException($"The user '{user}' is not authorized for this view."))(BR-WEBAPI-018). - Deliberately skipped when the user is unknown — the source comment states "user may be null before credentials are demanded", i.e. the challenge round-trip is not logged as a security event.
GetContextformats the log state asUser: {userId}\nPage: {requestUri}(BR-WEBAPI-018).- Set
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, $"The user '{user}' is not authorized.")(BR-WEBAPI-018). - Returns 401 Unauthorized (not 403), and echoes the resolved user name in the response body.
Process flow¶
flowchart TD
Start([OP-08 returned false]) --> NullCheck["Enforce.ArgumentNotNull<br>checks"]
NullCheck --> UserId["user =<br>environmentService.<br>UserId("]
UserId --> Known{user known?}
Known -->|Yes| LogSec["LogException(<br>SecurityException)"]
Known -->|No| Skip[Skip logging]
LogSec --> Response["Set 401 response with<br>message"]
Skip --> Response
Failure and edge-case behavior¶
- A missing
ILogServicethrows here (fail-closed), in contrast to the graceful degradation in Post-process an API response.
Note: Statements marked with ** could not be confirmed; treat as unknown until verified.
Related documentation¶
Sources¶
src/SAIF.Web.API/SaifAuthorizeAttribute.cs