[2023.3.x] ClaimsPrincipal inconsistent

[2023.3.x] ClaimsPrincipal inconsistent

avatar

Good morning,
After this week updates I've noticed few of my API endpoints are not behaving correctly, refusing my authentication verification.
It is simple check against ClaimsPrincipal NameIdentifier. Authentication set to WS-Federation.
I have two test endpoints setup for it. One just returns $ClaimsPrincipal, the other one is extracting Nameidentifier:
(($ClaimsPrincipal | ConvertFrom-Json).Claims | Where-Object -Property Type -EQ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value
This value is translated differently in PSU web test, returning "Name" property instead.
Same endpoint run trough browser returns correctly "NameIdentifier" which is slightly different name.
The last invokation trough "Invoke-RestMethod" and token I used for users before now returns "PowershellUniversal" as Nameidentifier.
I'm not sure what happened or if it's intended behaviour, as I've tested the output of powershell script for the user with his token to make sure it works. Workaround would be to rewrite the check for Name.
Thanks for any info on this.

All Comments (4)

avatar

Hello,

Thank you for the detailed report, the three test results made this much faster to pin down.

What you are seeing is expected behaviour, and it did not change in a recent update.
The nameidentifier claim is issued by your identity provider, not by PowerShell Universal.
Only the interactive browser sign in goes through WS-Federation to your ADFS or Entra.

That is why it is the only path that carries a real per user nameidentifier.
App tokens work differently.

A PowerShell Universal app token contains no nameidentifier claim at all.
It carries the user name in this claim:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name

It also carries a fixed subject value of PowerShellUniversal.
.NET maps that subject onto the nameidentifier claim while it validates the token.

That is why you read PowerShellUniversal there.
The value is the token subject, and it is the same for every app token, so it can never identify the calling user.
I reproduced this in a test environment to be sure.

I ran the same token against 2026.1.5, 2026.2.5, 2026.3.0 and 2026.3.1, and the result was identical on all four.
The cleanest fix is the $Identity variable, which holds the identity name of the caller.
It returns the correct user on every path, including app tokens.
$ClaimsPrincipal.Identity.Name gives you the same value.

Your own idea of checking Name instead is correct, so either option will work.
Two things would help me close this out.

First, could you confirm the exact version you run, before and after the update?
The version recorded on your case reads 2023.3.x, which is not a PowerShell Universal version number.

Second, do you use an authentication script, or any role or claim policy script, that calls PowerShell Universal cmdlets?

There is a known issue in the 2026.3 line that affects scripts calling these cmdlets, and a fix is targeted for an upcoming release (2026.3.2.0).
If you updated this week, that is the part that could genuinely have stopped working.

For reference:
App tokens and their claims: https://docs.devolutions.net/powershell-universal/security/app-tokens
API endpoint variables: https://docs.devolutions.net/powershell-universal/api/endpoints
WS-Federation: https://docs.devolutions.net/powershell-universal/security/enterprise-security/ws-federation

Best regards,

Patrick Ouimet

avatar

Hello, thanks for clarification. Version I have now is 2026.3.1.
I used the Name identification before but more usernames had spaces and NameIdentifier was basically their SamAccountName.
I've quickly tested this endpoint:

$Identity
$ClaimsPrincipal.Identity.Name
(($ClaimsPrincipal | ConvertFrom-Json).Claims | Where-Object -Property Type -EQ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name").Value

With result in browser as:
["server admin",null,"Server Admin"]
Powershell:

server admin

server admin

Still a bit strange that the browser has capital letters. Second line returned null for every user.
I'll work with $Identity then, thanks again!

avatar

Hello prajerl,

Version 2026.3.2 is now available and should contain a fix for this issue.

Could you update to this version and tell us if this is still occurring?

Best regards,

Patrick Ouimet

avatar

Hello Patrick,
the update fixed most of the things, thanks.
I had to change the suggested line a bit to make it work as the others:

$Identity
($ClaimsPrincipal | ConvertFrom-JSON).Identity.Name
(($ClaimsPrincipal | ConvertFrom-Json).Claims | Where-Object -Property Type -EQ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name").Value

It's now properly showing the "Name" for each line.

Have a great day!