Classify authenticated user¶
Classification happens once, at construction. clsSystemUser binds to Active Directory using either elevated credentials read from an XML properties file or credentials passed directly by the caller, resolves the authenticated principal's directory entry, and derives a UserTypes value that every IsXxx property and downstream operation relies on for the lifetime of the object.
| Field | Value |
|---|---|
| Operation ID | OP-SU-01 |
| Trigger | Caller constructs clsSystemUser with either (inPropertiesFileName, inPropertiesFilePath, inSecurityPrincipal) or (inSecurityPrincipal, inUserid, inPWD) |
| Inputs | clsSecurityPrincipal (domain, user name, roles); elevated bind user ID and password (read from XML or passed directly) |
| Outputs | Populated m_DirServer and m_DirUser context; m_UserType classification; UserType and IsXxx properties derived from it |
| Primary components | clsSystemUser.New(...), clsSystemUser.Initialize(...), clsSystemUser.GetUserType() |
| Entry point | Business\SAIF.Business.Security.SystemUser\clsSystemUser.vb |
Steps¶
- Resolve elevated bind credentials. The three-argument constructor opens the named properties file through
clsProperties, reads theONLINE/SECURITY/USERIDandONLINE/SECURITY/PASSWORDnodes, and passes them toInitialize. - On failure: any exception while reading the properties file or nodes is wrapped and re-thrown as
ApplicationException("Error while retrieving security user from properties.", ex). - The
Finallyblock always disposes theclsPropertiesinstance if it was created. - The two-argument constructor (
inSecurityPrincipal,inUserid,inPWD) skips this step and callsInitializedirectly with caller-supplied credentials. - Bind to the correct LDAP path.
InitializeinspectsinSecurityPrincipal.Domain. If the domain (case-insensitively) isSAIF,clsDirectoryServerconnects to"LDAP://" + Domainusing the resolved bind user ID as-is (BR-013). - Otherwise, the same connection is made but the bind user ID is prefixed with
"saif\"before use (BR-013). - Resolve the authenticated principal or fall back to unauthenticated. If
m_SecPrinc.UserNameis non-Nothingand non-empty, the directory server looks the user up by that user name and classification proceeds viaGetUserType()(step 4) (BR-005). - If
UserNameisNothingor empty (the unauthenticated-caller path used by the online login application), the directory server instead looks up the raw bind user ID (inUserid) andm_UserTypeis set directly toUnauthorizedwithout runningGetUserType()(BR-005). - Classify by domain (
GetUserType). For aSAIF-domain principal, the classification isSAIFEmployeeimmediately, with no group checks performed (BR-001). - Classify EXTERNAL-domain principals by prioritized group membership. For an
EXTERNAL-domain principal,GetUserType()evaluatesm_SecPrinc.IsInRole(...)in a fixed priority order and stops at the first match (BR-002): agents,Producers, orARPAgents→AgentBookkeepers→BookkeeperFeeAuditors→AuditorGroups→GroupLoss Control→LossControlMCO→MCOMedical Providers→MedProvpolicyholders→PolicyHolderWorkers→Worker- If none of the above groups match and the user name equals
WEBCOMP: classification falls back toSAIFEmployee(BR-003). - If none of the above match at all: classification is
Unauthorized. - Classify any other domain as unauthorized. A domain that is neither
SAIFnorEXTERNALclassifies asUnauthorizedwith no group evaluation (BR-004). - Expose the classification.
m_UserTypeis stored on aSharedfield and read back through theUserTypeproperty and the family ofIsXxxBoolean properties (IsAgent,IsBookkeeper,IsSAIFEmployee,IsUnAuthorized, etc.) for the remainder of the object's use.
Process flow¶
The following diagram visualizes this operation's control flow.
flowchart TD
Start([Constructor invoked]) --> Creds{Which constructor?}
Creds -->|3-arg| ReadXml[Read elevated bind credentials from XML]
Creds -->|2-arg| Init[Initialize with supplied credentials]
ReadXml --> Init
Init --> Bind{Domain = SAIF?}
Bind -->|Yes| BindSaif[Bind LDAP with bind user ID as-is]
Bind -->|No| BindExt[Bind LDAP with saif\ prefix]
BindSaif --> HasUser{UserName populated?}
BindExt --> HasUser
HasUser -->|No| Unauth([Unauthorized - unauthenticated caller])
HasUser -->|Yes| DomainCheck{Domain value}
DomainCheck -->|SAIF| Emp([SAIFEmployee])
DomainCheck -->|EXTERNAL| Roles[Evaluate group checks in priority order]
DomainCheck -->|Other| UnauthDomain([Unauthorized])
Roles --> Match{Group match found?}
Match -->|Yes| Typed([Matching UserType])
Match -->|No| Webcomp{UserName = WEBCOMP?}
Webcomp -->|Yes| Emp
Webcomp -->|No| UnauthNoMatch([Unauthorized])
Failure and edge-case behavior¶
- A missing or unreadable elevated-credentials properties file aborts construction entirely via a thrown
ApplicationException; there is no fallback classification for this path. - An unauthenticated caller (empty
UserName) is always classifiedUnauthorizedregardless of domain, without evaluating anyIsInRolechecks. - The EXTERNAL group-priority order is fixed in code; a user in multiple mapped groups is classified by whichever group is checked first, not by any explicit precedence configuration.*
WEBCOMPis the only user name with a name-based fallback; all other unmatched EXTERNAL users areUnauthorized.m_UserTypeis aSharedfield on the class rather than an instance field, so classification state is process-wide rather than per-instance.*
Related documentation¶
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
Business\SAIF.Business.Security.SystemUser\clsSystemUser.vb