Skip to content

Generate a Microsoft identity principal for local development

Need to exercise different users and roles before wiring production login? The Microsoft identity header adapter can construct a principal from development HTTP headers. This is identity simulation, not token validation.

x-ms-client-principal is Base64-encoded JSON — an unsigned assertion, not a signed bearer token. Arc’s header handlers decode it and construct claims; they do not validate a signature, issuer, or audience. Header presence and valid JSON do not prove who sent it.

Use manually supplied headers only on an isolated, loopback-bound development host. In production, either configure a real token/cookie authentication scheme or accept these assertions only from a trusted authenticated ingress. That ingress must strip and replace all incoming identity headers, and the backend must not be reachable through a bypass route. An arbitrary browser or proxy sending these headers is not trustworthy.

The authorization tutorial shows the ASP.NET registration and middleware placement for a Development-only fixture. The lightweight host authentication is a different setup; do not mix their APIs.

The adapter expects all three headers:

HeaderContent
x-ms-client-principalBase64 JSON following the client principal shape
x-ms-client-principal-idThe selected user’s stable identifier
x-ms-client-principal-nameThe selected user’s display name or email

Save this synthetic fixture as principal.json in your local application workspace:

{
"identityProvider": "aad",
"userId": "e7f664ca-4ecc-45be-84cf-74b6240d049a",
"userDetails": "jane.doe@contoso.com",
"userRoles": ["anonymous", "authenticated", "Librarian"],
"claims": [
{
"typ": "preferred_username",
"val": "jane.doe@contoso.com"
},
{
"typ": "name",
"val": "Jane Doe"
},
{
"typ": "given_name",
"val": "Jane"
},
{
"typ": "family_name",
"val": "Doe"
},
{
"typ": "oid",
"val": "e7f664ca-4ecc-45be-84cf-74b6240d049a"
}
]
}

userRoles is mapped to role claims by the header adapter. Include Librarian for the successful tutorial case; remove it for an authenticated-but-not-authorized case. A role field returned by IProvideIdentityDetails would not have the same effect.

Encode locally, keeping the result on one line:

Terminal window
python3 -c 'import base64,pathlib; print(base64.b64encode(pathlib.Path("principal.json").read_bytes()).decode())'

A local editor’s Base64 action is another option. Do not submit real identity payloads to an online encoder. Base64 provides neither confidentiality nor authenticity.

In ModHeader, create a development-only profile and add an include URL filter before enabling it. For the tutorial Vite server, use ^http://localhost:5173/.*$. Add a separate ^http://localhost:5000/.*$ only when testing that backend directly. If you use a different local port, update the filter; never select all requests.

Set:

  • x-ms-client-principal-id: e7f664ca-4ecc-45be-84cf-74b6240d049a
  • x-ms-client-principal-name: jane.doe@contoso.com
  • x-ms-client-principal: the one-line Base64 output above

Older ModHeader header-field example; replace its All requests scope with a localhost include filter

Use separate filtered profiles for different synthetic users. Confirm in browser developer tools that headers are sent only to your intended localhost application.

  • No headers: protected operations reject an unauthenticated caller.
  • Valid fixture without Librarian: authentication succeeds but role-protected operations reject access.
  • Fixture with Librarian: role-protected operations can execute, subject to their other checks.
  • Identity-details provider returning IsUserAuthorized: false: /.cratis/me rejects that identity result. This does not replace operation authorization.

These checks test the adapter and your authorization configuration, not production token verification. For production, independently test ingress header replacement, blocked direct backend access, and the real authentication scheme. See identity and access for how claims, details, operation permissions, and tenant membership differ.