---
title: SAIF.Framework.SecurityModule architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.SecurityModule
reference_type: package
---

# SAIF.Framework.SecurityModule architecture

SAIF.Framework.SecurityModule is an ASP.NET `IHttpModule`-based authentication module that hooks the `HttpApplication.AuthenticateRequest` pipeline event and orchestrates Windows authentication for hosted web applications, using either an encrypted-cookie fast path or an NTLM/Basic browser challenge depending on whether the requesting host is classified as internal or external.

## Responsibilities
- Plug into the ASP.NET request pipeline via `clsSecurityModule.Init`, wiring `AuthRequest_Handler` to `HttpApplication.AuthenticateRequest`.
- Determine whether a request's host is "internal" or "external" and route it to the corresponding authentication strategy (`InternalUserAuthenticator` / `ExternalUserAuthenticator`).
- Perform silent re-authentication from an encrypted `SAIFAUTH` cookie by decrypting it (DPAPI) and exchanging the recovered credentials for a Windows logon token.
- Fall back to an NTLM/Basic browser credential challenge (internal hosts) or a redirect to a configured login page (external hosts) when cookie authentication fails.
- Provide cross-cutting DPAPI-based value encryption/decryption (`DPAPI`) and structured log4net-backed diagnostic logging (`mdlLogging`) used throughout the module.
- Handle authentication-flow exceptions, distinguishing benign `ThreadAbortException`s (from `Response.Redirect`) from real errors, and redirect real errors to a configured error page.

Source: `SAIF.Framework.SecurityModule\clsSecurityModule.vb`, `SAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vb`.

## Component boundaries
- `clsSecurityModule` (implements `System.Web.IHttpModule`): pipeline entry point. Registers `AuthRequest_Handler` on `HttpApplication.AuthenticateRequest`, catches and routes exceptions to `ErrorPage`, and owns the `sec-errorpage` setting. Source: `SAIF.Framework.SecurityModule\clsSecurityModule.vb`.
- `UserAuthenticator` (abstract base) with `ExternalUserAuthenticator` and `InternalUserAuthenticator` subclasses: factory-selected (`UserAuthenticator.Find`) strategy layer that decides internal-vs-external handling and defines the abstract `Authenticate(WebContext)` contract; also owns the "already authenticated" short-circuit (`IsAuthenticated`). Source: `SAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vb`.
- `CookieAuthenticator`: decrypts and validates the `SAIFAUTH` cookie, obtains a Windows logon token via `TokenProvider`, and builds/assigns the `WindowsIdentity`/`WindowsPrincipal`. Source: `SAIF.Framework.SecurityModule\Authenticators\CookieAuthenticator.vb`.
- `BrowserAuthenticator`: issues the HTTP 401 response with `WWW-Authenticate` (`NTLM`/configured type, plus `Basic realm="SAIF"`) to trigger a native browser credential prompt for internal hosts when cookie authentication fails. Source: `SAIF.Framework.SecurityModule\Authenticators\BrowserAuthenticator.vb`.
- `TokenProvider` (Friend-scoped): wraps Win32 `LogonUser`/`DuplicateToken`/token-release P/Invoke calls (`advapi32.dll`, `Kernel32.dll`) to exchange decrypted credentials for a Windows token. Source: `SAIF.Framework.SecurityModule\TokenProvider.vb`.
- `DPAPI`: wraps Win32 `CryptProtectData`/`CryptUnprotectData` (`crypt32.dll`) for encrypting/decrypting the `SAIFAUTH` cookie value and other secrets. Source: `SAIF.Framework.SecurityModule\DAPIEncrypt.vb`.
- `mdlLogging`: shared log4net-backed logging facility (`Log`, `LogInfo`/`LogWarn`/`LogError`/`LogDebug`) consumed by every class in the module, formatting entries with host address, request URL, application name, and a reflection-derived call-stack trail. Source: `SAIF.Framework.SecurityModule\mdlLogging.vb`.

This is a leaf/utility library: its `.vbproj` contains no `<ProjectReference>` elements to other SAIF.Framework.* projects.*

## Interaction model
- The module is consumed by hosting ASP.NET web applications, which register `clsSecurityModule` in `Web.config`'s `<httpModules>`/`<system.webServer><modules>` section (inferred from the `IHttpModule` implementation; no consumer `Web.config` exists inside this library's own folder to confirm registration).**
- Control flow on each request: `clsSecurityModule.AuthRequest_Handler` → `UserAuthenticator.IsAuthenticated` (short-circuit if already authenticated) → `UserAuthenticator.Find(host, ExternalHostNames)` selects `ExternalUserAuthenticator` or `InternalUserAuthenticator` → concrete `Authenticate(WebContext)` calls `CookieAuthenticator.Authenticate` → `CookieAuthenticator` decrypts the `SAIFAUTH` cookie via `DPAPI.Decrypt` and calls `TokenProvider.GetToken` → a `WindowsIdentity`/`WindowsPrincipal` is assigned to `HttpContext.Current.User`.
- On cookie-authentication failure, `ExternalUserAuthenticator` redirects to the configured login page (`sec-loginpage`); `InternalUserAuthenticator` falls back to `BrowserAuthenticator.Authenticate`, issuing an HTTP 401 NTLM/Basic challenge.
- Every class in the module calls into `mdlLogging` for diagnostic logging, and `DPAPI`/`TokenProvider` are invoked only from `CookieAuthenticator` within this control flow.
- Exceptions raised anywhere in the try block of `AuthRequest_Handler` are caught: `ThreadAbortException` (from `Response.Redirect`) is suppressed via `Thread.ResetAbort()`, and all other exceptions redirect to `ErrorPage` (`sec-errorpage`) with the exception message appended.

Source: `SAIF.Framework.SecurityModule\clsSecurityModule.vb`, `SAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vb`, `SAIF.Framework.SecurityModule\Authenticators\CookieAuthenticator.vb`, `SAIF.Framework.SecurityModule\Authenticators\BrowserAuthenticator.vb`, `SAIF.Framework.SecurityModule\TokenProvider.vb`, `SAIF.Framework.SecurityModule\DAPIEncrypt.vb`.

The following diagram shows the high-level component interactions within the authentication pipeline.

```mermaid
flowchart TD
	A[clsSecurityModule<br>IHttpModule] --> B[UserAuthenticator<br>factory / IsAuthenticated]
	B --> C[ExternalUserAuthenticator]
	B --> D[InternalUserAuthenticator]
	C --> E[CookieAuthenticator]
	D --> E
	E --> F[DPAPI<br>Decrypt SAIFAUTH cookie]
	E --> G[TokenProvider<br>Win32 LogonUser]
	C --> H[Login page redirect]
	D --> I[BrowserAuthenticator<br>NTLM/Basic 401 challenge]
	A --> J[mdlLogging<br>log4net diagnostics]
	E --> J
	G --> J
	F --> J
	I --> J
```

## Sequence diagram
The following diagram shows the primary request authentication sequence, including the cookie fast path and browser-challenge fallback.

```mermaid
sequenceDiagram
	participant Client
	participant clsSecurityModule
	participant UserAuthenticator
	participant CookieAuthenticator
	participant TokenProvider
	participant BrowserAuthenticator

	Client->>clsSecurityModule: HTTP request (AuthenticateRequest)
	clsSecurityModule->>UserAuthenticator: IsAuthenticated / Find(host)
	UserAuthenticator->>CookieAuthenticator: Authenticate(WebContext)
	CookieAuthenticator->>CookieAuthenticator: DPAPI.Decrypt(SAIFAUTH cookie)
	CookieAuthenticator->>TokenProvider: GetToken(username, password)
	TokenProvider-->>CookieAuthenticator: Windows token or failure
	CookieAuthenticator-->>UserAuthenticator: WindowsPrincipal or failure
	alt Cookie auth failed, external host
		UserAuthenticator-->>Client: Redirect to sec-loginpage
	else Cookie auth failed, internal host
		UserAuthenticator->>BrowserAuthenticator: Authenticate(response, authType)
		BrowserAuthenticator-->>Client: HTTP 401 WWW-Authenticate NTLM/Basic
	else Cookie auth succeeded
		clsSecurityModule-->>Client: Request proceeds authenticated
	end
```

## Design constraints
- No `<ProjectReference>` dependencies exist on other SAIF.Framework.* projects; the module is a self-contained leaf library.*
- The library targets .NET Framework `v3.5` and depends on unmanaged Win32 APIs (`advapi32.dll`, `Kernel32.dll` for logon/token handling; `crypt32.dll` for DPAPI), which ties authentication to the Windows platform and machine/user DPAPI key scope.
- Authentication behavior is driven by `AppSettings` keys (`sec-errorpage`, `ExternalHostNames`, `sec-loginpage`, `sec-browser-authtype`, `sec-logindomain`) read via `ConfigurationManager.AppSettings`, with code-level fallback defaults; no consumer `Web.config` exists in this library's own folder to confirm final registered values.*
- Host classification as "external" uses a case-insensitive substring match against the `ExternalHostNames` setting, directly determining which fallback path (login redirect vs. NTLM/Basic challenge) is used.
- `ThreadAbortException`s raised by `Response.Redirect` inside the authentication handler are explicitly suppressed via `Thread.ResetAbort()` so that normal redirects are not misreported as authentication errors.
- Assembly carries a `SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True)` attribute (declared in `clsSecurityModule.vb` and again in `DAPIEncrypt.vb`), reflecting the module's reliance on unmanaged P/Invoke calls; `TokenProvider.GetToken` additionally carries a method-level `SecurityPermissionAttribute(SecurityAction.Assert, ...)`.

> **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)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Framework.SecurityModule\clsSecurityModule.vb`
- `SAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vb`
- `SAIF.Framework.SecurityModule\Authenticators\CookieAuthenticator.vb`
- `SAIF.Framework.SecurityModule\Authenticators\BrowserAuthenticator.vb`
- `SAIF.Framework.SecurityModule\TokenProvider.vb`
- `SAIF.Framework.SecurityModule\DAPIEncrypt.vb`
- `SAIF.Framework.SecurityModule\mdlLogging.vb`
- `SAIF.Framework.SecurityModule\SAIF.Framework.SecurityModule.vbproj`
