---
title: Configure an outbound client to send OnBehalfOfUser
summary: Attaches a persistent OnBehalfOfUser header to an IHttpJsonClient instance.
status: draft
owner: SAIF Platform Team
last_reviewed: 2026-10-02
library: SAIF.NetCore.NtlmApiAuth
reference_type: package
operation_id: OP-09
trigger: Consumer client setup code
---

# Configure an outbound client to send OnBehalfOfUser

Attaches the current user's name as a persistent `OnBehalfOfUser` header on an `IHttpJsonClient`, so it is sent on every subsequent request made by that client instance.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-09 |
| **Trigger** | Consumer client setup code (typically after `SetNtlmAuthentication()`) |
| **Inputs** | `ICurrentUserService` |
| **Outputs** | `IHttpJsonClient` reconfigured with a persisted header |
| **Primary components** | `IHttpJsonClientExtensions.ConfigureOnBehalfOfUserAuthorization(ICurrentUserService)` |
| **Entry point** | `src/SAIF.NetCore.NtlmApiAuth/src/SAIF.NetCore.NtlmApiAuth/Extensions/IHttpJsonClientExtensions.cs` |

## Steps

1. Call `client.SetOptions(new HttpClientOptions { PersistHeadersAfterRequest = true })`. This **replaces** the client's entire existing `HttpClientOptions` object (retry delay, retry statuses, serializer, and any other previously-configured option), not just the persistence flag — a client that had other custom options set before this call loses them unless they are re-specified here. ([BR-NTLM-009](../business-rules.md#br-ntlm-009-header-configuration-enables-persistence))

   > **Origin**: Step 1 is implemented in [Configure options](../../saif-netcore-httpclients/operations/configure-options.md) (`SAIF.NetCore.HttpClients`) and executed on behalf of this operation.
2. Resolve the user name via [Get the current user name](get-current-user-name.md), embedded here for reference (`friendlyName` default `true`):
   - MVC clients read `IHttpContextAccessor.HttpContext.User.Identity.Name` (null-safe).
   - Blazor clients synchronously block on `AuthenticationStateProvider.GetAuthenticationStateAsync()` and then read `User.Identity.Name` from the result.
   - If `friendlyName` is `true` (the default), the resolved name is passed through `DomainlessUser()` before being returned; otherwise the raw name is returned. `null` is returned if there is no identity in either branch.

   > **Origin**: Step 2 is implemented in [Get the current user name](get-current-user-name.md) (`SAIF.NetCore.NtlmApiAuth`) and executed on behalf of this operation.
3. If the name is non-empty, call `client.Headers.Add("OnBehalfOfUser", username)`; this throws `ArgumentException` if the key already exists. ([BR-NTLM-009](../business-rules.md#br-ntlm-009-header-configuration-enables-persistence), [BR-NTLM-010](../business-rules.md#br-ntlm-010-header-added-only-when-non-blank%3B-duplicate-add-throws))
   - On each subsequent request made by this `IHttpJsonClient`, `HttpJsonClient.CreateRequest` copies the instance's custom `Headers` (including the `OnBehalfOfUser` header added here) onto the outbound RestSharp request, then conditionally clears the `Headers` collection: because step 1 set `PersistHeadersAfterRequest = true`, the clear is skipped and the header survives for the next request too, rather than being removed after a single use.

   > **Origin**: This sub-step is implemented in [Execute request](../../saif-netcore-httpclients/operations/execute-request.md) (`SAIF.NetCore.HttpClients`) and executed on behalf of this operation.

Because step 1 sets `PersistHeadersAfterRequest = true` before step 3 adds the header, the `OnBehalfOfUser` header added here is retained by the `IHttpJsonClient` and resent on every subsequent request made by that same client instance, where the receiving server reads it via the middleware described in [Convert the OnBehalfOfUser header into a claim](convert-header-to-claim.md).

## Process flow

```mermaid
flowchart TD
	Start([ConfigureOnBehalfOfUserAuthorization]) --> S1[SetOptions PersistHeadersAfterRequest true]
	S1 --> S2[Resolve current user name]
	S2 --> S3{Name non-empty?}
	S3 -->|No| End([No header added])
	S3 -->|Yes| S4["Headers.Add OnBehalfOfUser, name"]
	S4 --> End2([Header sent on every request])
```

## Failure and edge-case behavior
- If the target `IHttpJsonClient` outlives a single user (e.g. registered Singleton, or a cached/typed client), the first configured user's name is sent on every later request from that client instance, including requests made on behalf of other users.
- Calling this operation twice on the same client throws `ArgumentException` from the underlying `Dictionary.Add`.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `src/SAIF.NetCore.NtlmApiAuth/src/SAIF.NetCore.NtlmApiAuth/Extensions/IHttpJsonClientExtensions.cs`
