Skip to content

Principal identity initialization

Every other operation in this library depends on clsSecurityPrincipal already knowing who the caller is, so this is the first thing that runs on any request. It chooses between two identity sources — a decrypted Forms authentication ticket for web callers, or the Windows thread/process identity for everyone else — populates the principal from whichever source applies, and, if that identity is accepted as authenticated, impersonates it so later calls run in the caller's security context.

Field Value
Operation ID OP-001
Trigger clsSecurityPrincipal construction or Instance access
Inputs HttpContext.Current, Thread.CurrentPrincipal, current platform, existing Forms authentication cookie
Outputs Populated domain and user fields, base principal and identity, authentication flag, optional impersonation context
Primary components clsSecurityPrincipal.init, clsSecurityPrincipal.InitFormsIdentity, clsSecurityPrincipal.InitWindowsIdentity
Entry point SAIF.Framework.Security\clsSecurityPrincipal.vb

Steps

  1. Instance or the constructor first decides whether to reuse a principal already cached for the current web session or to build a fresh clsSecurityPrincipal. init() then routes to the Forms-identity path whenever the current thread principal is a GenericPrincipal backed by a FormsIdentity; every other case falls through to Windows-identity initialization.
  2. Authorization context: this routing decision establishes the subject that Authorization enforcement points later evaluate.
  3. On the Forms path, InitFormsIdentity() reads the Forms authentication cookie, decrypts the underlying ticket, splits its name into user and domain, marks the principal authenticated, and builds WindowsPrincipal / WindowsIdentity objects from the ticket's name so the rest of the library can treat a web login the same way it treats a Windows identity.
  4. If HttpContext or the cookie is missing: the method leaves the principal's fields unchanged rather than raising an error.
  5. On failure: a ticket-decryption exception is not caught locally, so it propagates to the caller.
  6. When the Forms path is not selected, InitWindowsIdentity() records the IsProduction flag, switches the AppDomain's principal policy to WindowsPrincipal, clears the cached list of available resources, and picks either WindowsIdentity.GetCurrent() or Thread.CurrentPrincipal as the base identity, depending on the current platform and the type of principal already attached to the thread.
  7. If the caller is on the Windows platform and the thread principal is not already a WindowsPrincipal: the method falls back to WindowsIdentity.GetCurrent() so the resolved identity is authoritative regardless of what the thread started with.
  8. Before the principal is considered usable, the web branch rejects anonymous identities and screens out the built-in ASPNET worker account, then backfills domain\user into the principal fields — enforcing BR-004 so the ASP.NET process identity is never mistaken for a real end user.
  9. Authorization context: whether this gate passes determines if subsequent checks in Programmatic authorization checks run under an authenticated subject at all.
  10. If the identity is anonymous or fails the worker-account gate: the principal remains unauthenticated, and no domain/user values are backfilled.
  11. Once authentication succeeds, the resolved base identity is impersonated and the resulting context is stored in m_ImpersonatedUser, so downstream authorization calls and any external service calls execute as the caller rather than the hosting process.
  12. If authentication did not succeed: no impersonation context is created, and later operations run under whatever identity the host process already had.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Principal requested]) --> Mode{Forms identity?}
    Mode -->|Yes| Forms[Decrypt Forms cookie]
    Mode -->|No| Windows[Resolve Windows identity]
    Forms --> Auth{Authenticated?}
    Windows --> Auth
    Auth -->|Yes| Imp[Impersonate base identity]
    Auth -->|No| EndErr([Leave principal unauthenticated])
    Imp --> EndOk([Principal ready])

Failure and edge-case behavior

  • A missing Forms authentication cookie leaves the principal uninitialized rather than raising an explicit error.
  • Forms ticket decryption failures are not wrapped locally and propagate to the caller.
  • Web callers whose resolved identity is anonymous, or matches the ASPNET worker account, are left unauthenticated and receive no impersonation context.

Sources

  • SAIF.Framework.Security\clsSecurityPrincipal.vb
  • SAIF.Framework.Security\AppGlobal.vb