---
title: SAIF.Presentation.Web.Controls.V2.Menu 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.Controls.V2.Menu
reference_type: package
---

# SAIF.Presentation.Web.Controls.V2.Menu security and authorization

This page documents authorization mechanisms implemented or consumed by this library. Authentication is handled entirely by infrastructure (NTLM/AD) and is not application-level — all code receives a `WindowsIdentity` on the request context.

## Authorization architecture

`SAIF.Presentation.Web.Controls.V2.Menu` makes **no Active Directory calls and no authorization decision of its own**. It is a pure consumer of the per-user authorization set produced by `SAIF.Business.Menu` and cached in `Session("navdata")` as a `NavigationContext`. Every rendered link, accordion category, favourite, and toolbar button is emitted only when the corresponding entry exists in that user's `MenuAuthorizedItems` collection and carries the appropriate flag. Because this is UI-side trimming, it is a **presentation-layer authorization projection, not an access control barrier** — the enforceable page-level check is performed by `SAIF.Presentation.Web.MVC.clsControllerBase`.

```mermaid
flowchart TD
    A["Page request"] --> B{"Session('navdata')<br>present?"}
    B -- yes --> C["Reuse cached NavigationContext"]
    B -- no --> D["Request.LogonUserIdentity.Name<br>strip DOMAIN, upper-case"]
    D --> E["New NavigationContext(userid)<br>loads MenuAuthorizedItems"]
    E --> C
    C --> F["SAIFMenu: categories + items<br>where IsVisible"]
    C --> G["SAIFMenu: Favorites branch"]
    C --> H["SAIFMenuTop: category links<br>where IsVisible"]
    C --> I["SAIFMenuTop: GetCurrentPage()<br>toolbar capability flags"]
    I --> J["Insert / Save / Delete / Print /<br>Download / Prefs / Help buttons"]
```

## AD resource catalog

No AD resource names, LDAP paths, `System.DirectoryServices` usage, WCF `SecurityService` proxies, or authorization attributes appear in this library.

| Resource name | Purpose | Enforcement point | Source |
| --- | --- | --- | --- |
| _(none)_ | No Active Directory resource name is referenced in this library | — | — |

The only `Security`-namespace artifacts are the `AspNetHostingPermission(SecurityAction.Demand / InheritanceDemand, Level:=AspNetHostingPermissionLevel.Minimal)` CAS declarations on `SAIFImageButton`. These are standard ASP.NET custom-control hosting-permission declarations and grant no application privilege. `SAIFMenu.vb` also carries `Imports SAIF.Framework.Security`, but no member of that namespace is referenced in the file.*

## Authorization enforcement points

### Programmatic authorization checks

| Class | Method | Resource / Role | Check type | Source |
| --- | --- | --- | --- | --- |
| `SAIFMenu` | `GetNavigationData` | Authorization-set acquisition — returns `Session("navdata")` when present; otherwise reads `HttpContext.Current.Request.LogonUserIdentity.Name`, strips the domain prefix, upper-cases it, and constructs `New NavigationContext(userid)`, then caches it in session | `IsAuthorized` (indirect via `NavigationContext`) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |
| `SAIFMenuTop` | `GetNavigationData` | Identical logic to the row above (session-first, then `LogonUserIdentity.Name`) | `IsAuthorized` (indirect) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| `SAIFMenu` | `AddLinks` — category panes | An accordion pane is created for a category only when `MenuAuthorizedItems.AppItemsByCategory(Category).Where(Function(AuthItem) AuthItem.IsVisible = True).Count > 0` | HasAccess (menu trimming) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |
| `SAIFMenu` | `AddLinks` — item links | Iterates `MenuAuthorizedItems.ApplicationItems` and emits a `LinkButton` only `If Item.IsVisible` | HasAccess (menu trimming) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |
| `SAIFMenu` | `AddFavorites` | Iterates `MenuAuthorizedItems.Favorites` only — favorites are themselves a branch of the per-user authorization query | HasAccess (menu trimming) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |
| `SAIFMenu` | `AddFavorites` — external-client link | `If AppGlobal.EnvironmentService.IsClientExternal` adds the "Change Password" link (`ChangePWLink`) to the favorites list | HasAccess (audience gate) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |
| `SAIFMenuTop` | `BuildLinkCollection` | Iterates `MenuAuthorizedItems.AppItemsByCategory(SelectedCategory)` and emits a link only `If Item.IsVisible` | HasAccess (menu trimming) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| `SAIFMenuTop` | `Page_PreLoad` | `CurrentPage = NavigationData.GetCurrentPage()`; each toolbar button is made `Visible`/`Enabled` only when the matching `clsMenuAuthorizedItem` flag is set: `IsDisplayInsert`, `IsDisplaySave`, `IsDisplayDelete`, `IsDisplayPrint`, `IsDisplayDownload`, `IsDisplaySavePreferences`, `IsDisplayHelp` | HasAccess (per-page action authorization) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| `SAIFMenu` / `SAIFMenuTop` | `NavigateToItem` | The clicked sequence number is resolved back through `NavigationData.MenuAuthorizedItems.Item(ItemSeq)` before `MenuNavigate` is raised with the item's `ApplicationPath` and `PageLink` | HasAccess (navigation resolution) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`; `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| `SAIFMenu` / `SAIFMenuTop` | `CurrentItem` / `CurrentPage` | Resolve the active page through `NavigationData.GetCurrentItem` / `GetItem` / `GetCurrentPage`, all of which query only the authorized set | HasAccess (current-page resolution) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`; `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |

<!-- No attribute-based authorization (e.g. [SAIFAuthorize]) exists in this library. -->

### Per-page action-capability matrix

Each capability is a flag on the user's own `clsMenuAuthorizedItem` row for the current page, sourced from `MENU_PAGE` in `SAIF.Business.Menu`.

| Toolbar action | Gating flag | Underlying column | Enforcement point |
| --- | --- | --- | --- |
| Insert | `IsDisplayInsert` | `MENU_PAGE.INSERT_FLAG` | `SAIFMenuTop.Page_PreLoad` (see [BR-MENU-059](business-rules.md#br-menu-059-toolbar-buttons-appear-only-when-the-current-page-enables-them)) |
| Save | `IsDisplaySave` | `MENU_PAGE.SAVE_FLAG` | `SAIFMenuTop.Page_PreLoad` |
| Delete | `IsDisplayDelete` | `MENU_PAGE.DELETE_FLAG` | `SAIFMenuTop.Page_PreLoad` |
| Print | `IsDisplayPrint` | `MENU_PAGE.PRINT_FLAG` | `SAIFMenuTop.Page_PreLoad` |
| Download | `IsDisplayDownload` | `MENU_PAGE.DOWNLOAD_FLAG` | `SAIFMenuTop.Page_PreLoad` |
| Save preferences | `IsDisplaySavePreferences` | `MENU_PAGE.SAVE_PREFERENCES_FLAG` | `SAIFMenuTop.Page_PreLoad` |
| Help | `IsDisplayHelp` | `MENU_PAGE.HELP_FLAG` | `SAIFMenuTop.Page_PreLoad` |

## Data-level authorization

| Entity type | Validation method | Mechanism | Source |
| --- | --- | --- | --- |
| Menu item / authorization set | `NavigationContext` / `clsMenuAuthorizedItemCollection` | Identity-derived set acquisition — the menu user is taken from the authenticated Windows identity (`Request.LogonUserIdentity.Name`, `DOMAIN\` prefix stripped, upper-cased), never from a client-supplied value | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`; `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| Menu item click target | `clsMenuAuthorizedItem` | `MenuAuthorizedItems.Item(ItemSeq)` resolves the click target, so the navigation target is always taken from the authorized set rather than posted data (see [BR-MENU-046](business-rules.md#br-menu-046-navigation-targets-come-only-from-the-authorised-item)) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`; `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb` |
| Client audience | External vs. internal client | `AppGlobal.EnvironmentService.IsClientExternal` controls whether the "Change Password" link is offered (see [BR-MENU-023](business-rules.md#br-menu-023-the-change-password-link-is-offered-only-to-external-clients)) | `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb` |

No entity-ownership validation (policy/claim/account) and no segregation-of-duties checks exist in this library.

## Notes
- Mark inferred statements with `*` and unknown statements with `**`. Do not use bold inline confidence labels.
- AD resource names listed here use base names only. The framework appends `Resource` (production) or `TestResource` (non-production) at runtime. This library declares no AD resource names of its own.
- Hiding and disabling a toolbar button prevents the UI from raising the corresponding `ToolbarClick` event, but the controls do not re-check the capability flag inside the click handlers (see [BR-MENU-077](business-rules.md#br-menu-077-toolbar-click-handling-does-not-re-check-visibility-or-enabled-state)), so a forged postback targeting a disabled action is not demonstrably blocked at this layer.*
- The `navdata` session cache is never invalidated on menu-security change, so a privilege revocation takes effect only after the session ends.* `SAIF.Presentation.Web.MVC.clsControllerBase` clears `Session("navdata")` when it denies a page, which is the only invalidation path observed across the scanned libraries.
- `AppGlobal.EnvironmentService.IsClientExternal` is supplied by an external SAIF framework package not present in this repository; the rule that classifies a client as external cannot be confirmed here.**

> **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
- [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)
- [Control catalog](control-catalog.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb`
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFImageButton.vb`
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIF.Presentation.Web.Controls.V2.Menu.vbproj`
- `SAIF.Presentation.Web.MVC/NavigationContext.vb`
