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, wiringAuthRequest_HandlertoHttpApplication.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
SAIFAUTHcookie 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
ThreadAbortExceptions (fromResponse.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(implementsSystem.Web.IHttpModule): pipeline entry point. RegistersAuthRequest_HandleronHttpApplication.AuthenticateRequest, catches and routes exceptions toErrorPage, and owns thesec-errorpagesetting. Source:SAIF.Framework.SecurityModule\clsSecurityModule.vb.UserAuthenticator(abstract base) withExternalUserAuthenticatorandInternalUserAuthenticatorsubclasses: factory-selected (UserAuthenticator.Find) strategy layer that decides internal-vs-external handling and defines the abstractAuthenticate(WebContext)contract; also owns the "already authenticated" short-circuit (IsAuthenticated). Source:SAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vb.CookieAuthenticator: decrypts and validates theSAIFAUTHcookie, obtains a Windows logon token viaTokenProvider, and builds/assigns theWindowsIdentity/WindowsPrincipal. Source:SAIF.Framework.SecurityModule\Authenticators\CookieAuthenticator.vb.BrowserAuthenticator: issues the HTTP 401 response withWWW-Authenticate(NTLM/configured type, plusBasic 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 Win32LogonUser/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 Win32CryptProtectData/CryptUnprotectData(crypt32.dll) for encrypting/decrypting theSAIFAUTHcookie 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
clsSecurityModuleinWeb.config's<httpModules>/<system.webServer><modules>section (inferred from theIHttpModuleimplementation; no consumerWeb.configexists 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)selectsExternalUserAuthenticatororInternalUserAuthenticator→ concreteAuthenticate(WebContext)callsCookieAuthenticator.Authenticate→CookieAuthenticatordecrypts theSAIFAUTHcookie viaDPAPI.Decryptand callsTokenProvider.GetToken→ aWindowsIdentity/WindowsPrincipalis assigned toHttpContext.Current.User. - On cookie-authentication failure,
ExternalUserAuthenticatorredirects to the configured login page (sec-loginpage);InternalUserAuthenticatorfalls back toBrowserAuthenticator.Authenticate, issuing an HTTP 401 NTLM/Basic challenge. - Every class in the module calls into
mdlLoggingfor diagnostic logging, andDPAPI/TokenProviderare invoked only fromCookieAuthenticatorwithin this control flow. - Exceptions raised anywhere in the try block of
AuthRequest_Handlerare caught:ThreadAbortException(fromResponse.Redirect) is suppressed viaThread.ResetAbort(), and all other exceptions redirect toErrorPage(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.
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.
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.5and depends on unmanaged Win32 APIs (advapi32.dll,Kernel32.dllfor logon/token handling;crypt32.dllfor DPAPI), which ties authentication to the Windows platform and machine/user DPAPI key scope. - Authentication behavior is driven by
AppSettingskeys (sec-errorpage,ExternalHostNames,sec-loginpage,sec-browser-authtype,sec-logindomain) read viaConfigurationManager.AppSettings, with code-level fallback defaults; no consumerWeb.configexists in this library's own folder to confirm final registered values.* - Host classification as "external" uses a case-insensitive substring match against the
ExternalHostNamessetting, directly determining which fallback path (login redirect vs. NTLM/Basic challenge) is used. ThreadAbortExceptions raised byResponse.Redirectinside the authentication handler are explicitly suppressed viaThread.ResetAbort()so that normal redirects are not misreported as authentication errors.- Assembly carries a
SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True)attribute (declared inclsSecurityModule.vband again inDAPIEncrypt.vb), reflecting the module's reliance on unmanaged P/Invoke calls;TokenProvider.GetTokenadditionally carries a method-levelSecurityPermissionAttribute(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¶
Sources¶
SAIF.Framework.SecurityModule\clsSecurityModule.vbSAIF.Framework.SecurityModule\Authenticators\UserAuthenticator.vbSAIF.Framework.SecurityModule\Authenticators\CookieAuthenticator.vbSAIF.Framework.SecurityModule\Authenticators\BrowserAuthenticator.vbSAIF.Framework.SecurityModule\TokenProvider.vbSAIF.Framework.SecurityModule\DAPIEncrypt.vbSAIF.Framework.SecurityModule\mdlLogging.vbSAIF.Framework.SecurityModule\SAIF.Framework.SecurityModule.vbproj