SAIF.Framework.Security architecture¶
SAIF.Framework.Security is the framework-level security primitives layer for SAIF BOF applications. It does not own application authorization policy; instead it provides the mechanisms (clsSecurityPrincipal, Utilities.MachineSecurityService, clsAccountMaintProxy) that consuming applications use to authenticate/impersonate Windows identities and delegate authorization decisions to a centralized WCF SecurityService and, in parallel, to a legacy ASMX clsADServices AD web service. The library currently sits mid-migration between these two integration paths.
Responsibilities¶
- Capture and manage the current security principal: Windows/Forms identity initialization, NTLM authentication, and impersonation (
clsSecurityPrincipal,clsElevateImpersonate,SAIFCredentials). - Delegate resource and role authorization decisions to the centralized WCF
SecurityService(clsSecurityPrincipal.IsAuthorized/IsInRole/IsAuthorizedSecurityService). - Provide a legacy path to the ASMX
clsADServicesAD web service for resource-access checks and user lookups (clsAccountMaintProxy, plusclsSecurityPrincipal.GetEmailAddress/GetIDNumber/GetDefaultPrinter). - Authorize machine/service accounts against AD security groups via WCF group-membership enumeration (
Utilities.MachineSecurityService). - Resolve environment/config settings for both integration paths (
AppGlobalmodule,EnvironmentServices\EnvironmentExtensions). - Provide general-purpose cryptography helpers (DPAPI, AES, MD5, X.509 certificate operations) used by login/credential flows and otherwise standalone.
- Expose a COM-visible authorization wrapper for non-.NET/legacy Windows clients (
clsSecurityPrincipalCOM).
Component boundaries¶
clsSecurityPrincipal: Core security principal wrapper — identity capture, NTLM authentication, and the primary WCFSecurityServiceauthorization dispatch (IsAuthorized,IsInRole,IsAuthorizedSecurityService).clsSecurityPrincipalCOM: COM interop boundary; delegatesIsAuthorized/IsInRolecalls toclsSecurityPrincipalfor COM-visible Windows clients.clsSecurityPrincipalCollection: Stub/placeholder collection type; holds a singleclsSecurityPrincipalfield with no working members — effectively a no-op/incomplete type, not part of the active interaction model.clsAccountMaintProxy: Boundary to the legacy ASMXclsADServicesweb reference — account lookups and resource-access checks (cached/external variants).Utilities.MachineSecurityService(IMachineSecurityService): Machine/service-account authorization boundary — queries WCFSecurityService.GetUsersByGroupdirectly and performs in-process membership matching (distinct from the booleanIsAuthorizedservice call used elsewhere).clsElevateImpersonate/SAIFCredentials: Win32 impersonation boundary (LogonUser/DuplicateTokenP/Invoke) used for explicit-credential authentication scenarios.clsSAIFLoginInfo: Login orchestration boundary — authenticates viaclsSecurityPrincipal, then manages Forms auth and DPAPI-encrypted "automated login" cookies.AppGlobalmodule: Environment/config resolution boundary — lazily resolves the correctEnvironmentServiceBase(Web vs. Windows) from theSAIF.Framework.Security.EnvironmentApiproject reference.Cryptography\(AES,Certificates,MD5Hash) andDAPIEncrypt.vb(DPAPI): Standalone cryptography utility boundary, consumed by login/credential flows but with no dependency on the authorization paths.Service References\SecurityService\Reference.vb(auto-generatedSecurityService.SecurityClient): WCF proxy boundary for the modern authorization/user-lookup path.Web References\ADServices\Reference.vb(auto-generatedclsADServices): ASMX proxy boundary for the legacy authorization/user-lookup path.
Interaction model¶
- A consuming application obtains
clsSecurityPrincipal.Instance(session-cached perHttpContext); the constructor initializes either a Forms identity (decrypted from aFormsAuthenticationcookie) or a Windows identity (fromThread.CurrentPrincipal/WindowsIdentity.GetCurrent()). - Authorization calls (
IsAuthorized,IsInRole) construct aBasicHttpBindingWCF client per call (no client instance reuse/caching) and delegate to the centralized WCFSecurityService, passing the authenticated principal's unqualified user name and a fully-qualified, environment-suffixed resource/role string. Utilities.MachineSecurityServiceindependently resolves its own WCF endpoint and callsSecurityService.GetUsersByGroupto enumerate group membership, then performs a linear case-insensitive match against the supplied machine name — this is membership enumeration, not a boolean authorization call, and fails closed (returns not-authorized) if the WCF call throws.clsAccountMaintProxyand selectclsSecurityPrincipalmethods (GetEmailAddress,GetIDNumber,GetDefaultPrinter) instead call the legacy ASMXclsADServicesproxy (HasAccess/HasAccessCache/HasAccessExternal/HasAccessCacheExternal/WhoHasAccessCache) for resource-access checks and directory lookups.clsSAIFLoginInfo.Login()authenticates viaclsSecurityPrincipal, then sets a DPAPI-encryptedSAIFAUTHcookie and aFormsAuthenticationcookie for subsequent Forms-identity initialization.- This library depends on
SAIF.Framework.Security.EnvironmentApi(local project reference) for all configuration/environment resolution; it has no dependency on SAIF BOF business-object base classes and does not participate in the BOF data-portal pipeline.
Architecture diagram¶
The following diagram shows the two parallel integration paths — the primary WCF SecurityService path and the legacy ASMX clsADServices path — both fed by the same principal/identity layer.
flowchart TD
Consumer[Consuming application] --> Principal[clsSecurityPrincipal<br>identity + authorization]
Consumer --> AccountProxy[clsAccountMaintProxy<br>legacy resource checks]
Consumer --> MachineSvc[Utilities.MachineSecurityService<br>machine/service-account auth]
Principal -->|IsAuthorized / IsInRole| WCFClient[SecurityService.SecurityClient<br>WCF proxy]
Principal -->|GetEmailAddress / GetIDNumber / GetDefaultPrinter| ASMXClient[clsADServices<br>ASMX proxy]
AccountProxy -->|HasAccess / HasAccessCache / WhoHasAccessCache| ASMXClient
MachineSvc -->|GetUsersByGroup| WCFClient
WCFClient --> SecuritySvc[WCF SecurityService<br>http://saifonline/WCF/Security]
ASMXClient --> ADSvc[Legacy clsADServices.asmx]
Principal --> EnvApi[AppGlobal /<br>SAIF.Framework.Security.EnvironmentApi]
AccountProxy --> EnvApi
MachineSvc --> EnvApi
Sequence diagram¶
The following diagram shows the primary resource-authorization request sequence via the WCF path.
sequenceDiagram
participant Consumer as Consuming application
participant Principal as clsSecurityPrincipal
participant WCFClient as SecurityService.SecurityClient
participant SecuritySvc as WCF SecurityService
Consumer->>Principal: IsAuthorized(ResourceName)
Principal->>Principal: Build Domain\ResourceName[Test]Resource
Principal->>WCFClient: New SecurityClient(binding, endpoint)
Principal->>WCFClient: IsAuthorized(m_UserName, RoleName)
WCFClient->>SecuritySvc: SOAP IsAuthorized call
SecuritySvc-->>WCFClient: authorization result
WCFClient-->>Principal: authorization result
Principal-->>Consumer: True/False
Design constraints¶
- The two integration paths (WCF
SecurityServiceand legacy ASMXclsADServices) reflect an in-progress migration:IsAuthorized/IsInRole/MachineSecurityServiceuse the WCF endpoint, whileclsAccountMaintProxyandclsSecurityPrincipal.GetEmailAddress/GetIDNumber/GetDefaultPrinterstill use the legacy ASMX endpoint.* - The WCF and legacy ASMX paths use inconsistent environment-suffix conventions: the WCF path appends
Resource/TestResource, while the legacy ASMX path (clsAccountMaintProxy) appends only a plainTestsuffix — same intent (environment isolation), different naming format. - No resource/AD group names are statically defined in this library; all resource and role names are caller-supplied strings, making this a pure mechanism layer rather than a policy owner.
clsSecurityPrincipalconstructs a new WCFBasicHttpBindingclient per authorization call rather than reusing/caching a client instance.Utilities.MachineSecurityServiceresolves its environment/config settings via aCustomEnvironmentServiceinstance hard-coded toCustomEnvironment.Prod, distinct from theAppGlobal.EnvironmentServicesingleton used byclsSecurityPrincipal— the two classes also read the same logical config key under different casings (securityserviceurlvs.securityServiceUrl).*Utilities.MachineSecurityService.IsAuthorizedfails closed (returns not-authorized) when the underlying WCF call throws, since the exception handler only logs viaDebug.WriteLineand never sets the result to found.clsSecurityPrincipalCollectionis a stub/placeholder type with no working members and is not part of the active interaction model.
Related documentation¶
- Index
- Overview
- Dependencies
- Operations and processes
- Business rules
- Configuration
- Security and authorization
- API reference
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.Framework.Security\clsSecurityPrincipal.vbSAIF.Framework.Security\clsSecurityPrincipalCOM.vbSAIF.Framework.Security\clsSecurityPrincipalCollection.vbSAIF.Framework.Security\clsAccountMaintProxy.vbSAIF.Framework.Security\clsElevateImpersonate.vbSAIF.Framework.Security\SAIFCredentials.vbSAIF.Framework.Security\clsSAIFLoginInfo.vbSAIF.Framework.Security\AppGlobal.vbSAIF.Framework.Security\Utilities\MachineSecurityService.vbSAIF.Framework.Security\Utilities\IMachineSecurityService.vbSAIF.Framework.Security\Service References\SecurityService\Reference.vbSAIF.Framework.Security\Web References\ADServices\Reference.vbSAIF.Framework.Security\app.config