---
title: BolMiddleware security and authorization
summary: Authorization mechanisms, enforcement points, data-level access control, and security risks in BolMiddleware.
status: draft
owner: SAIF IT Core Services
last_reviewed: 2026-10-12
library: BolMiddleware
reference_type: package
---

# BolMiddleware security and authorization

This page documents the authorization mechanisms that BolMiddleware implements or consumes. Authentication is not performed here: sign-in is inherited from `OidcRazorStartup`, and `BolRazorLayoutStartup` only registers the legacy BOL authentication middleware in dependency injection, without adding it to the pipeline.* The library defines no attribute-based authorization and no literal Active Directory resource names; roles are supplied by calling code.

## Authorization architecture
Authorization is a thin, programmatic layer. `SecurityService` answers questions about the current user through `IHttpContextAccessor`, the platform `ISecurityClient` for role checks and external user lookup (`GetExternalUser`), and the Policy Core API client (`IPolicyCoreApiClient.IsValidPolicyForUser`) for policy access. Page models call it; the role name is supplied by the consuming application. Policy access is enforced softly: a failed check sets an error message and flags but does not stop the handler ([BR-BOLMIDDLEWARE-009](business-rules.md#br-bolmiddleware-009-policy-access-validation)). The only security attribute in the library is `[IgnoreAntiforgeryToken]` on `BolMenuModel`, which disables anti-forgery validation for every derived page.

```mermaid
flowchart TD
	Page[Consumer page model] --> Menu[BolMenuModel IsAuthorizedAsync]
	Page --> Policy[BolPolicyModel GetPolicyHeader]
	Menu --> Svc[SecurityService]
	Policy --> Svc
	Svc -->|Role check and external user lookup| SC[ISecurityClient IsAuthorized and GetExternalUser]
	Svc -->|Policy access check| PC[IPolicyCoreApiClient IsValidPolicyForUser]
	Svc -->|Identity name| HC[IHttpContextAccessor]
```

## AD resource catalog
| Resource name | Purpose | Enforcement point | Source |
| --- | --- | --- | --- |
| None defined in this library | The role name is a caller-supplied argument; the commented-out `AgencyExternal` and `DivPolicyholderExternal` names are not active | `BolMenuModel.IsAuthorizedAsync` to `SecurityService.IsAuthorizedAsync` to `ISecurityClient.IsAuthorized` | src/BolMiddleware/Models/BolMenuModel.cs, src/BolMiddleware/Services/Security/SecurityService.cs |

## Authorization enforcement points
### Attribute-based authorization
No authorization attributes exist. `[IgnoreAntiforgeryToken]` on `BolMenuModel` is a security-relevant attribute that disables anti-forgery token validation for all pages that derive from it ([SR-02](#security-risks)).

### Programmatic authorization checks
| ID | Class | Method | Resource / Role | Check type | Source |
| --- | --- | --- | --- | --- | --- |
| SEC-01 | `SecurityService` | `IsAuthorizedAsync(role)` | Caller-supplied role; user id is the identity name without the `DOMAIN\` prefix | `ISecurityClient.IsAuthorized`; returns `false` when there is no principal | src/BolMiddleware/Services/Security/SecurityService.cs |
| SEC-02 | `BolMenuModel` | `IsAuthorizedAsync(role)` | Same as SEC-01 | Public wrapper over SEC-01 for consumer pages and views; nothing in the library calls it, so enforcement depends on consumer code | src/BolMiddleware/Models/BolMenuModel.cs |
| SEC-03 | `SecurityService` | `IsUserExternal` | Identity domain is not `SAIF` ([BR-BOLMIDDLEWARE-005](business-rules.md#br-bolmiddleware-005-external-user-detection)) | Identity name test; an un-prefixed name is classified as external* | src/BolMiddleware/Services/Security/SecurityService.cs |
| SEC-04 | `BolContextModel` and `SecurityService` | `GetExternalUserInformationForContext` and `GetCurrentExternalUserAsync` | External user record ([BR-BOLMIDDLEWARE-006](business-rules.md#br-bolmiddleware-006-external-user-information-lookup-once)) | `ISecurityClient.GetExternalUser`; runs only while the cookie `userState` is `New`, and exceptions are swallowed | src/BolMiddleware/Models/BolContextModel.cs, src/BolMiddleware/Services/Security/SecurityService.cs |
| SEC-05 | `BolMenuModel` and `MenuService` | `OnPageHandlerExecuting` menu load | Current user id | `IBolMenuApiClient.GetBusinessOnlineMenu`, cached in session under `BolMenu`; per-user filtering is presumed to occur in the BOL Menu API* | src/BolMiddleware/Models/BolMenuModel.cs, src/BolMiddleware/Services/Menu/MenuService.cs |
| SEC-06 | Layouts | `ChangeContextPrivilege` context textbox gate ([BR-BOLMIDDLEWARE-019](business-rules.md#br-bolmiddleware-019-context-textbox-visibility)) | Flag set by the consuming application; the library never assigns it | Presentation only: the server reads `contextvalue` from any post regardless of the flag | src/BolMiddleware/Models/BolMenuModel.cs, src/BolMiddleware/Pages/Shared/_PolicyLayout.cshtml |
| SEC-07 | `_BolPageHeaderPartial` | Profile and logoff links | External user ([BR-BOLMIDDLEWARE-018](business-rules.md#br-bolmiddleware-018-external-profile-and-logoff-links)) | Presentation only | src/BolMiddleware/Pages/Shared/_BolPageHeaderPartial.cshtml |

Seven programmatic enforcement points exist. Four make decisions (SEC-01, SEC-03, SEC-04, SEC-05), SEC-02 is a wrapper over SEC-01, and SEC-06 and SEC-07 are presentation only. The policy ownership check is a data-level check, listed as DLA-01 below.

## Data-level authorization
| ID | Entity type | Validation method | Mechanism | Source |
| --- | --- | --- | --- | --- |
| DLA-01 | Policy | `SecurityService.IsValidPolicyForCurrentUser` | `IPolicyCoreApiClient.IsValidPolicyForUser` answers whether the current user may view the policy | src/BolMiddleware/Services/Security/SecurityService.cs |
| DLA-02 | Policy association | `PolicyHeaderService.GetHeader` | When `customerId` is greater than 0: user type `POLCY` replaces the associations with those returned for `customerId`; user type `AGNCY` keeps only associations containing a policy whose `AgencyId` equals `customerId`; other user types are not filtered ([BR-BOLMIDDLEWARE-013](business-rules.md#br-bolmiddleware-013-external-association-filtering)) | src/BolMiddleware/Services/Headers/Policy/PolicyHeaderService.cs |
| DLA-03 | Policy dropdown visibility | `BolPolicyModel.CanViewPolicyDropdown` | External: requires a `CustomerId` equal to the header relationship policy or rate account, or a `ManualAffiliation` association with `CustomerId` equal to `ParentAccount`. Internal: requires the policy or parent account to equal the relationship policy or rate account ([BR-BOLMIDDLEWARE-012](business-rules.md)). A presentation gate on top of DLA-02; a chosen policy is re-validated by DLA-01 on the next post | src/BolMiddleware/Models/BolPolicyModel.cs |

Web contexts loaded by `cid` or `WebContextId` are accepted without an ownership check* ([SR-03](#security-risks)).

## Security interfaces and contracts
| Interface / Class | Role | Consumers | Source |
| --- | --- | --- | --- |
| `ISecurityService` | Facade for identity, role, external user, and policy access questions | `BolContextModel`, `BolMenuModel`, `BolPolicyModel` through `IBolServicesContainer` | src/BolMiddleware/Services/Security/ISecurityService.cs |
| `ISecurityClient` | Platform client for role checks and external user lookup, not registered by this library* | `SecurityService` | src/BolMiddleware/Services/Security/SecurityService.cs |
| `ContextCookie` | Unsigned cookie payload holding user type and state | `BolContextModel` | src/BolMiddleware/Models/ContextCookie.cs |

## Inherited security
The startup base `OidcRazorStartup` overrides `ConfigureServices` (it adds Razor Pages, optionally adds Newtonsoft JSON, then calls the base) and inherits `AppStartup.Configure`, which sets up request buffering, optional session, authentication, HSTS, optional HTTPS redirection, static files, routing, authorization, and UI and logger setup. `BolRazorLayoutStartup` sets `EnableLegacyBolAuthMiddleware` to true, which only controls whether `LegacyBolAuthMiddleware` is registered in dependency injection; per the framework documentation `AppStartup.Configure` never adds it to the request pipeline, so BolMiddleware does not by itself run the legacy BOL authentication middleware.* Whether a consuming application adds it explicitly is not visible from this library**.

## Security risks
The following risks were found in source. Severity is an assessment from reading the code, not a tested result.

| ID | Risk | Detail | Severity | Source |
| --- | --- | --- | --- | --- |
| SR-01 | Unsigned `BolContext` cookie is trusted | The cookie holds user type, state, and the context result and is deserialized without a signature, so a client can alter it | High* | src/BolMiddleware/Models/BolContextModel.cs |
| SR-02 | Anti-forgery disabled | `[IgnoreAntiforgeryToken]` on `BolMenuModel` disables validation on every derived page, including the `MenuItemClick` post | Medium | src/BolMiddleware/Models/BolMenuModel.cs |
| SR-03 | Context id without ownership check | A `cid` or `WebContextId` loads that context for any caller | Medium* | src/BolMiddleware/Models/BolContextModel.cs |
| SR-04 | Soft policy enforcement | The handler runs after a failed policy access check; derived pages must test `AccessAllowed` | Medium | src/BolMiddleware/Models/BolPolicyModel.cs |
| SR-05 | Cookies without Secure or SameSite | The `BolContext` cookie is HttpOnly only, and expiry uses local `DateTime.Now` | Low | src/BolMiddleware/Services/CookieService/CookieService.cs |
| SR-06 | Exception text shown to users | `ex.Message` is stored in `ErrorMessage` and rendered in the error view | Low | src/BolMiddleware/Models/BolPolicyModel.cs |
| SR-07 | Sensitive request data may reach logs | `GetFrameworkLoggingInfo` can serialize form values, query values, the referrer, and context items. No live caller exists in this library, so exposure depends on consuming applications and no logging event is observed here | Low* | src/BolMiddleware/Services/Context/WebContextExtensions.cs |
| SR-08 | Script string concatenation | `MenuNavigation.js` builds hidden inputs by concatenating `#web-context-value` and `#web-context-id` values into an HTML string without escaping (self-XSS) | Low | src/BolMiddleware/wwwroot/js/MenuNavigation.js |
| SR-09 | Redirect from posted values | `targetApp` and `targetPage` build the redirect without an allow-list or URL encoding | Low* | src/BolMiddleware/Models/BolMenuModel.cs, src/BolMiddleware/Contracts/NavigationOptions.cs |
| SR-10 | Third-party scripts and styles | The font stylesheet CDN link and the Google tag script carry no subresource integrity, and the tag sends analytics data to a third party | Low | src/BolMiddleware/Pages/Shared/_BolCoreScriptsHeaderPartial.cshtml, src/BolMiddleware/Pages/Shared/_PolicyLayout.cshtml |

## Notes
- No segregation of duties rules exist in this library.
- Two sync-over-async calls (`Task.Result` on policy access, and the user lookup) can block request threads.
- `BolLayoutStartup.cs` is entirely commented out and adds no security behavior.
- `IBolContextApiClient` is registered twice; the last registration wins.

> **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
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Service registration](service-registration.md)
- [API reference](api/index.md)

## Sources
- src/BolMiddleware/Services/Security/SecurityService.cs
- src/BolMiddleware/Services/Security/ISecurityService.cs
- src/BolMiddleware/Services/Menu/MenuService.cs
- src/BolMiddleware/Models/BolContextModel.cs
- src/BolMiddleware/Models/BolMenuModel.cs
- src/BolMiddleware/Models/BolPolicyModel.cs
- src/BolMiddleware/Models/ContextCookie.cs
- src/BolMiddleware/Services/CookieService/CookieService.cs
- src/BolMiddleware/Services/Context/WebContextExtensions.cs
- src/BolMiddleware/Services/Headers/Policy/PolicyHeaderService.cs
- src/BolMiddleware/Contracts/NavigationOptions.cs
- src/BolMiddleware/wwwroot/js/MenuNavigation.js
- src/BolMiddleware/Pages/Shared/_PolicyLayout.cshtml
- src/BolMiddleware/Pages/Shared/_BolPageHeaderPartial.cshtml
- src/BolMiddleware/Pages/Shared/_BolCoreScriptsHeaderPartial.cshtml
- src/BolMiddleware/BolRazorLayoutStartup.cs
- src/BolMiddleware/BolLayoutStartup.cs
