---
title: SAIF.Presentation.Web.MVC security and authorization
summary: Authorization requirements, AD resource groups, security enforcement points, and data-level access control.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.MVC
reference_type: package
---

# SAIF.Presentation.Web.MVC security and authorization

This page documents authorization mechanisms implemented or consumed by this library. Authentication is handled entirely by infrastructure (NTLM/Basic) and is not application-level — all code receives an authenticated identity that this library wraps as a `clsSecurityPrincipal`.

## Authorization architecture

`SAIF.Presentation.Web.MVC` is the only library in this repository that takes an enforceable authorization decision. On every page initialization, `clsControllerBase.Initialize` runs a fixed sequence: session-timeout handling, `SecurityCheck` (establish the `clsSecurityPrincipal` on the model context, emit the `STYPE` cookie, or issue a `401` challenge / throw), lazy construction of the per-user `NavigationContext` into `Session("navdata")`, and finally `RedirectUnauthorizedUsers`, which denies the request by redirecting to `/OnlineLogin/LoginScreen.aspx` when the requested application + page is not in the user's menu-authorization set. No Active Directory group is queried anywhere in this library — page authorization is entirely menu-data-driven (Oracle `MENU` schema, resolved via `SAIF.Business.Menu`), and the caller's identity is supplied by infrastructure rather than by this library.

The following diagram shows the fixed order of the security steps performed on every page initialization.

```mermaid
sequenceDiagram
    participant P as ViewPageBase.Page_Init
    participant C as clsControllerBase
    participant S as clsSecurityPrincipal
    participant N as NavigationContext (Session navdata)
    P->>C: Initialize()
    C->>C: IsSessionTimedOut? redirect (internal vs. external)
    C->>S: SecurityCheck() - New clsSecurityPrincipal(Platform.Web)
    alt IsAuthenticated
        C->>C: set Context.SecurityPrincipal, write STYPE cookie
    else internal address
        C-->>P: 401 + WWW-Authenticate NTLM / Basic realm SAIF
    else external address
        C-->>P: Throw "Not Authorized."
    end
    C->>N: New NavigationContext(Context.UserID) if session empty
    C->>N: RedirectUnauthorizedUsers - IsMenuItem(app, page)
    alt not a menu item
        C-->>P: clear navdata + redirect /OnlineLogin/LoginScreen.aspx
    else authorized
        C->>C: Model.Pre_Init, Load, query strings, CheckContext
    end
```

## AD resource catalog

| Resource name | Purpose | Enforcement point | Source |
| --- | --- | --- | --- |
| _(none)_ | No Active Directory resource name, LDAP path, `System.DirectoryServices` usage, WCF `SecurityService` proxy, or `[SAIFAuthorize]` attribute is present in this library | — | — |

The authorization "resources" used here are `(applicationCode, pageLink)` pairs from the Oracle `MENU` schema, resolved per user by `SAIF.Business.Menu`. `clsSecurityPrincipal` (from the external `SAIF.Framework.Security` package, not present in this repository) is used only as an identity carrier — this library calls `IsAuthenticated`, `UserName`, and the shared `CurrentThreadUser`; it never calls `IsAuthorized` or `IsInRole`.

## Authorization enforcement points

No MVC controller actions or methods in this library carry declarative authorization attributes; all enforcement is programmatic.

### Programmatic authorization checks

| Class | Method | Resource / Role | Check type | Source |
| --- | --- | --- | --- | --- |
| `clsControllerBase` | `SecurityCheck` — principal establishment | n/a | Identity gate: constructs `New clsSecurityPrincipal(Platform.Web)` and assigns it to the model context only when `IsAuthenticated` | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `SecurityCheck` — internal 401 challenge | n/a | Challenge: for an unauthenticated internal-address caller, clears the response, sets `401`, appends `WWW-Authenticate: NTLM`/`Basic realm="SAIF"`, ends the response | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `SecurityCheck` — external deny | n/a | Hard deny: `Throw New Exception("Not Authorized.")` for an unauthenticated non-internal caller | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `SecurityCheck` — `STYPE` cookie emission | n/a | Identity propagation: writes response cookie `STYPE` = upper-cased `UserName` on successful authentication | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `RedirectUnauthorizedUsers` | `(applicationCode, pageLink)` from `Request.Url.LocalPath` | `IsMenuItem` — the enforceable page-authorization check; denies by clearing `Session("navdata")` and redirecting to `/OnlineLogin/LoginScreen.aspx` | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `Initialize` — authorization-set construction | User's menu-authorized item set | Authorization-set load: constructs `New NavigationContext(Context.UserID)` into `Session("navdata")` when empty, feeding the `IsMenuItem` check | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `Initialize` — session-timeout handling | n/a | Session gate: `IsSessionTimedOut` redirects internal clients to the app root with a timeout message, and all other clients to `/OnlineLogin/LoginScreen.aspx` with `SAIFAUTH` cleared | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `IsInsideClient` | n/a | Network-zone discriminator: matches `Request.UserHostAddress` against `10.*`, `131.131.*.*`, `127.0.0.1`; drives the session-timeout branch | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `HandleErrors` — error-page routing | n/a | Network-zone discriminator: routes internal addresses to the intranet error handler when `ErrorPageName` is unconfigured (information-exposure control)* | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `RedirectUnauthorizedUsers` — audit trace | n/a | Audit: writes an `Info` trace of app/page/result and a `Warning` trace `"Menu denied access"` on denial, stamped with `CurrentThreadUser` | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsControllerBase` | `UnInitialize` | n/a | State guard: persists the model back into session only when `SecurityPrincipal IsNot Nothing`, so an unauthenticated request never seeds session model state | SAIF.Presentation.Web.MVC/clsControllerBase.vb |

`ViewPageBase.Page_Init` is the single entry point that triggers this pipeline: it obtains the controller from the factory and calls `Initialize()` before any page logic runs. `clsControllerBase.Navigate2` additionally attaches a freshly constructed `clsSecurityPrincipal` to each new model instance so that multi-model pages never inherit an empty security context.

## Data-level authorization

| Entity type | Validation method | Mechanism | Source |
| --- | --- | --- | --- |
| `NavigationContext` / `clsMenuAuthorizedItemCollection` | Identity-derived authorization set | The menu set is loaded for `Context.UserID`, which returns `SecurityPrincipal.UserName.ToUpper()` (or `""` when no principal is set) — derived from the established identity, not from any request parameter | SAIF.Presentation.Web.MVC/clsContext.vb; SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| Application code + page link | URL-derived resource identity | The protected resource is computed from `Request.Url.LocalPath.Remove(0,1).Split("/"c)` — the actual request path, not posted or query-string data | SAIF.Presentation.Web.MVC/clsControllerBase.vb |
| `clsPreferences` | User-scoped preference storage | Constructed with `Context.SecurityPrincipal.UserName().ToString` and the application name, so preferences are partitioned by user | SAIF.Presentation.Web.MVC/clsModelBase.vb |
| `Context` table (cross-application context hand-off) | Session-scoped context scoping | `RetrieveContext`/`SaveContext`/`GetPID` key every row on session ID plus source/target application name; rows are deleted after retrieval ([BR-MVC-017](business-rules.md#br-mvc-017-cross-application-context-is-consumed-exactly-once)) | SAIF.Presentation.Web.MVC/clsContext.vb |

No entity-ownership validation (policy/claim/account belongs to the caller), no segregation-of-duties checks, no machine-account authorization, and no WCF `SecurityService` calls exist in this library.

## Security interfaces and contracts

| Interface / Class | Role | Consumers | Source |
| --- | --- | --- | --- |
| `NavigationContext` | Holds the per-user, per-session `MenuAuthorizedItems` set and exposes `IsMenuItem(app, page)`, the sole enforceable authorization decision in this library | `clsControllerBase` | SAIF.Presentation.Web.MVC/NavigationContext.vb |
| `clsSecurityPrincipal` | External identity carrier (from `SAIF.Framework.Security`, not present in this repository); exposes `IsAuthenticated`, `UserName`, and the shared `CurrentThreadUser` | `clsControllerBase`, `clsContext`, `clsModelBase` | External package — not in this repository |

## Notes
- `clsSecurityPrincipal`, `clsEnvironment.InternalAddress`, and `AppGlobal.EnvironmentService` come from external SAIF framework packages not present in this repository, so the concrete identity-resolution and internal-address rules cannot be confirmed here.**
- The `STYPE` cookie carries the upper-cased user name and is written without `HttpOnly`, `Secure`, or an expiry in this code path; whether those attributes are applied by configuration is not determinable from this repository.**
- `RedirectUnauthorizedUsers` dereferences `Session("navdata")` directly; if the session entry were absent at that point a null-reference would occur rather than a deny. In the observed flow `Initialize` always populates it first.*
- Denial redirects to `/OnlineLogin/LoginScreen.aspx` rather than returning `403`, so a menu-authorization failure is presented to the user as a re-login rather than as an access-denied result.*
- AD resource names, where present, use base names only. The framework appends `Resource` (production) or `TestResource` (non-production) at runtime — not applicable here since no AD resources are referenced.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **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.

## Sources
- SAIF.Presentation.Web.MVC/clsControllerBase.vb
- SAIF.Presentation.Web.MVC/clsContext.vb
- SAIF.Presentation.Web.MVC/clsModelBase.vb
- SAIF.Presentation.Web.MVC/clsOnlineContext.vb
- SAIF.Presentation.Web.MVC/NavigationContext.vb
- SAIF.Presentation.Web.MVC/ViewPageBase.aspx.vb
- SAIF.Presentation.Web.MVC/ViewControlBase.ascx.vb
