Skip to content

Authentication and authorization

Identity is established, where it is established at all, entirely by IIS at the transport layer; nothing in any of the six service classes carries an authorization attribute or a programmatic role check. SecurityService implements the authorization provider used by other SAIF applications (IsAuthorized/IsAuthorized2), but that authorization logic protects only the resources those callers separately guard — it does not gate any operation on this host itself.

Authentication

Aspect Finding
Mechanism IIS-configured Windows and/or anonymous authentication, varying by deployment variant
Transport security Not declared in system.serviceModel bindings for the inbound services — default basicHttpBinding security mode
Client credential type Not declared for inbound services
Established by IIS site/application configuration — IISWindowsAuthInternal/IISAnonymousAuthInternal (Internal) and IISWindowsAuthExternal/IISAnonymousAuthExternal (External), values defined outside this repository
Identity type WindowsIdentity, where Windows authentication is enabled
Configured in pipelines/release.yml (per-variant IIS authentication switches)
Anonymous access Varies by deployment variant and environment — governed by pipeline variables not present in this repository

No service class, operation, or binding in this repository declares an authentication requirement in code; whatever a caller must present to reach an operation is entirely a function of the IIS site configuration applied at deploy time for the Internal or External variant. See Activation and hosting for the variant mapping.

Caller context

Aspect Finding
Context source OperationContext.Current.RequestContext (five of six services); HttpContext.Current (SecurityService.LogRequestDetails, PreferenceService.GetDefaultPrinter)
Consumed by WcfEnvironmentService constructor argument in FaxService, PreferenceService, WebContextService, ImagingService, SecurityService
Identity resolved to Environment track and per-track configuration access — not a caller identity; no operation resolves a caller's Windows or application identity for authorization purposes
Behavior without context Construction fails — all five services that build WcfEnvironmentService from OperationContext.Current.RequestContext are constructible only inside an active WCF operation context

Authorization enforcement

Mechanism Scope Declared in Effect
None in code — — Every dispatched message reaches its operation; access relies entirely on IIS authentication and network placement for the deployed variant

No service class in this host carries an authorization attribute, and no operation performs a programmatic role or permission check before executing its body. This is true of all 24 operations across all six services, including the five unconstrained FileService path operations and the ten SecurityService identity/authorization-provider operations. SecurityService.IsAuthorized/IsAuthorized2 compute an authorization answer for other applications to act on; they do not gate access to SecurityService itself or to any other operation on this host.

Access requirements by operation

Operation Requirement Enforced by On failure
ReadFile None in code — Call proceeds
ReadEntireFile None in code — Call proceeds
WriteFile None in code — Call proceeds
DeleteFile None in code — Call proceeds
Length None in code — Call proceeds
GetPreferences None in code — Call proceeds
SavePreferences None in code — Call proceeds
GetDefaultPrinter None in code — Call proceeds
Get None in code — Call proceeds
Save None in code — Call proceeds
CreateContext None in code — Call proceeds
QueueImage None in code — Call proceeds
ReserveImageId None in code — Call proceeds
SendFax None in code — Call proceeds
IsAuthorized None in code — Call proceeds
IsAuthorized2 None in code — Call proceeds
GetUser None in code — Call proceeds
GetSaifUserByUserId None in code — Call proceeds
GetSaifUserByEmployeeId None in code — Call proceeds
GetUserIdForEmployeeId None in code — Call proceeds
GetExternalUser None in code — Call proceeds
GetExternalUserByCustomerId None in code — Call proceeds
GetInjuredWorkerUserByCustomerId None in code — Call proceeds
GetUsersByGroup None in code — Call proceeds

Secrets handling

Secret Location Retrieved by Consumed by Notes
LOG_REQUEST_DETAILS Web.config appSettings ConfigurationManager.AppSettings["LOG_REQUEST_DETAILS"] inside an empty try/catch SecurityService Read into _logRequestDetails but never consulted — a dead kill switch (see Tech debt)
LDAP_EXTERNAL_KEY Web.config appSettings ConfigurationManager.AppSettings["LDAP_EXTERNAL_KEY"] inside an empty try/catch SecurityService Names the environment key holding the external LDAP host; falls back to a literal default when unresolved — not reproduced here
Application-pool credentials Pipeline variable group Architecture.ServiceAccounts.IIS ($(wcf.svc.username) / $(wcf.svc.password)) Release pipeline IIS application pool identity Not present in this repository as literal values — not reproduced here

No credential literal appears in any configuration file in this host.

Security findings

  • FileService accepts arbitrary paths across the network boundary with no authorization. FileService is registered at the route FileService and exposes five operations — ReadFile, ReadEntireFile, WriteFile, DeleteFile, Length — that each take a caller-supplied path string and act on it directly via System.IO, with no allow-list, no Path.GetFullPath containment check, and no caller-identity check. Any caller that can reach the route can therefore name any path the IIS application-pool identity can reach, including UNC paths. includeExceptionDetailInFaults="true" additionally returns filesystem exception detail — including resolved paths — to the caller on failure. See Tech debt.
  • SecurityService logs full request detail on every call, unconditionally. SecurityService.LogRequestDetails writes a JSON fragment containing the operation name and its arguments — including userId, employeeId, customerId, groupName, and role — into the IIS log via HttpContext.Current.Response.AppendToLog(msg), called at the top of every SecurityService operation. The LOG_REQUEST_DETAILS appSetting that appears intended to gate this is read into a field but never consulted, so the kill switch has no effect. See Tech debt.
  • ldap_external is a mutable private static field. It is mutated from an instance constructor on every request and read by the static method IsAuthorizedExternal; concurrent requests share and overwrite it, a cross-request shared-state hazard on the external authorization path. See Tech debt.
  • ErrorLogErrorHandler logs error.GetErrorLogFormattedException() together with the failing method signature and the calling user; exception messages originating from FileService and PreferenceService can contain caller-supplied path and user values, so those values reach the central exception log (see Faults and error pipeline).

Notes

  • Statements marked with * in this document set are inferred from surrounding evidence rather than stated directly in source.

Sources

  • src/WCF/SAIF.Services.WCF.Host/Services/FileService.cs
  • src/WCF/SAIF.Services.WCF.Host/Services/Security/SecurityService.cs
  • src/WCF/SAIF.Services.WCF.Host/Services/Security/AuthorizationCacheService.cs
  • src/WCF/SAIF.Services.WCF.Host/Web.Base.config
  • pipelines/release.yml