Claims and roles only working for some

Product: PowerShell Universal
Version: 2.4.1

Hey @adam

We use a number of roles for authenticated dashboards and using OIDC to authenticate against AAD. Only certain users are getting all claims from roles.ps1.

Users that authenticate only receive:
Operator
Reader
Execute

But other users receive the custom claims from AAD groups, I have tried increasing the MaxRequestHeadersTotalSize but did not work. Do you have any other suggestions?

Thanks

Are the users missing claims not receiving any claims from AAD? I would check to see what the $User object looks like in roles.ps1 for those users. It could be a configuration thing with AAD.

I’ll typically just convert it to JSON and export it.

$User | ConvertTo-Json | Out-File "$Env:Temp\$($User.Identity.Name).claims.json"

Typically, the max header issue would cause 500 errors when attempting to login. Any idea what the group membership count looks like for your users?

The membership count varies but I would say max group membership ~150. The users that are not getting claims, I do not see any group claims in the json file.

The App Reg does has groupMembershipClaims set to All in the manifest.

Interesting. Can you check one of the users that isn’t working and see if the Permissions and Consent are correct?

I wonder if it’s possible for a user to not consent to something during the first login and then PSU is failing to retrieve information.

This is what mine defaults look like.

Assignment Detail looks good on users with many groups associated with PSU Roles and on a user that only has one group assigned to a PSU Role.

In the claims json file, it does show the correct object id and tenant. But looking at it, for user that it is working on I see all of the group claims, but for users that it is not working on, I see this:

{
      "Type": "_claim_names",
      "Value": "{\"groups\":\"src1\"}",
      "ValueType": "JSON",
      "Issuer": "https://sts.windows.net/<tenantId>",
      "Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"
    },
    {
      "Type": "_claim_sources",
      "Value": "{\"src1\":{\"endpoint\":\"https://graph.windows.net/<tenantId>/users/<userObjectId>/getMemberObjects\"}}",
      "ValueType": "JSON",
      "Issuer": "https://sts.windows.net/<tenantId>/",
      "Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"
    }

Tenant and User Object ID were redacted, but are correct in the json file.

@adam

This looks to be a limitation with Azure AD, Group Overage Claim.

Please document the claim that represents group overage · Issue #39289 · MicrosoftDocs/azure-docs (github.com)

That would explain why some users are getting group claims and others are not.

Scroll down a little to Group overage claim

Microsoft provides an example of how to handle this:

SampleAzureADAuthentication/Startup.cs at master · mattruma/SampleAzureADAuthentication (github.com)

Specifically, SampleAzureADAuthentication/Startup.cs at 17d24adf0162366aa3758bf919998f15f0b20fd7 · mattruma/SampleAzureADAuthentication · GitHub

Not sure if it would apply to your code, but thought it may be helpful.

ahhhh interesting. Thanks for all the info. I’ll open an issue for this. I hadn’t run into this before.

I guess as a work around you could query graph yourself for the time being.

1 Like

@adam

Workaround if anyone else comes across this issue.

Add to roles.ps1 for any custom role:

if ($User.Claims.type -eq '_claim_names') {
    Try {
        $AppSettings = Get-Content -Path "$env:UAPath\appsettings.json" |ConvertFrom-Json
        $ClientId = $AppSettings.Authentication.OIDC.ClientID
        $ClientSecret = $AppSettings.Authentication.OIDC.ClientSecret
        $TenantId = ($User.Claims |Where-Object type -eq 'http://schemas.microsoft.com/identity/claims/tenantid').value
        $UserId = ($User.Claims |Where-Object type -eq 'http://schemas.microsoft.com/identity/claims/objectidentifier').value
        $Params = @{
            Uri = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
            Body = @{
                'client_id' = $ClientId
                'client_secret' = $ClientSecret
                'scope' = 'https://graph.microsoft.com/.default'
                'grant_type' = 'client_credentials'
            }
            Method = 'Post'
            ContentType = 'application/x-www-form-urlencoded'
            ErrorAction = 'Stop'
        }
        $Token = Invoke-RestMethod @Params |Select-Object -ExpandProperty access_token
        $Params = @{
            Uri = "https://graph.microsoft.com/v1.0/$TenantId/users/$UserId/getMemberObjects"
            Headers = @{
                Authorization = "Bearer $Token"
            }
            Method = 'Post'
            ContentType = 'application/json'
            Body = (@{
                securityEnabledOnly = $false
            } |ConvertTo-Json)
        }
        $GroupObjectId = (Invoke-RestMethod @Params).value
        $GroupObjectId -eq '<update to group object id>'
    }
    Catch {
        throw $_
    }
}
else {
    $User.HasClaim('groups', '<update to group object id>')
}
2 Likes