Not getting AD groups as claims with Okta authentication

Product: PowerShell Universal
Version: 2.9.2

Hey PSU folks,

Following documentation here, OpenID Connect - PowerShell Universal, starting at Configuring Okta, we’ve followed the steps and have been half way successful. We can authenticate with Okta (which is using DUO for MFA), but we are not getting our AD group memberships as claims.

The process I followed was to create the Okta app, then add the OIDC settings to my appsettings.json file and restart the service. This did not work, so I added the OIDC authentication type in PSU, configured all the settings the same as my appsettings.json file, confirmed the settings in my authentication.ps1 file, and restarted the service. Not we hit Okta, authenticate, DUO prompts us for MFA, and after confirming MFA I’m taken to PSU - but my AD group memberships are not coming over.

My Okta admin walked through the setup with me watching. Everything is setup the same way it is in the documentation. Including the settings for Group claim type = Filter, and the Groups claim filter = groups & Matches regex .*

My appsettings.json file, my authentication.ps1 file, and the OIDC authentication configuration in the web UI all have the same settings, and Scope is set to “openid profile groups”

I’m expecting this means when Okta performs the authentication it will pull over all my AD group memberships as claims; using .* for the filter. However, when I visit Security > Roles > View Claim Information I do not see any of my AD groups as claims.

In my roles.ps1 file I’ve dumped $UserInfo and $UserInfo.Groups to a text file, but they are both blank. I dumped $User to a file and found I have .Claims with various claims & I have .Identity. Having $User.Identity.Name -eq “My User Name” in my roles.ps1 file is how I’m able to assign the Administrator role to myself at this point in time. The documentation says to use $UserInfo.Groups -contains “AD Group/Claim Name”, but I don’t have anything in $UserInfo.Groups.

I’ve been banging my head for 2 days on this and not getting anywhere. Any ideas?

I enabled debug log level, but a log in just shows:

2022-04-07 12:51:46.078 -05:00 [INF] Evaluting claims for user@domain.com, Cache: False
2022-04-07 12:51:46.078 -05:00 [DBG] Running claims evaluation
2022-04-07 12:51:46.079 -05:00 [DBG] Evaluating roles.
2022-04-07 12:51:46.790 -05:00 [INF] user@domain.com is part of role Administrator

My authentication.ps1 file is:

Set-PSUAuthenticationMethod -Type "OpenIDConnect" -CallbackPath "/authorization-code/callback" -ClientId "<ID>" -ClientSecret "<Secret>" -Authority "https://domain.okta.com" -UseTokenLifetime $true -GetClaimsFromUserInfoEndpoint $true -SaveTokens $true -Scopes "openid profile groups"

My appsettings.json file is:

"Kestrel": {
    "Endpoints": {
      "HTTP": {
        "Url": "http://*:80"
      },
      
"HTTPS": {
        "Url": "https://*:443",
        "Certificate": {
          "Subject": "*.domain.com",
          "Store": "My",
          "Location": "LocalMachine"
        }
      }
    },

  "RedirectToHttps": "true"
  },
 
  "ApplicationInsights": {
    "InstrumentationKey": "<Key>"
  },

  "OIDC": {
    "Enabled": "true",
    "CallbackPath": "/authorization-code/callback",
    "ClientID": "ID",
    "ClientSecret": "Secret",
    "Resource": "",
    "Authority": "https://domain.okta.com",
    "ResponseType": "code",
    "SaveTokens": "true",
    "CorrelationCookieSameSite": "",
    "UseTokenLifetime": true,
    "Scope": "openid profile groups",
    "GetUserInfo": true
  }

The claims I get out of $User.Claims, and what is reflected when I click View Claim Information:

* Type: name - Value: <Name from AD> - Issuer: https://domain.okta.com
* Type: jti- Value: ID.<string> - Issuer: https://domain.okta.com
* Type: http://schemas.microsoft.com/claims/authnmethodsreferences - Value: otp - Issuer: https://domain.okta.com
* Type: http://schemas.microsoft.com/claims/authnmethodsreferences - Value: pwd - Issuer: https://domain.okta.com
* Type: http://schemas.microsoft.com/identity/claims/identityprovider - Value: <string>- Issuer: https://domain.okta.com
* Type: preferred_username - Value: <UPN from AD> - Issuer: https://domain.okta.com
* Type: auth_time - Value: <string> - Issuer: https://domain.okta.com
* Type: http://schemas.microsoft.com/ws/2008/06/identity/claims/role - Value: Administrator- Issuer: https://www.poshtools.com
* Type: given_name - Value: <GivenName from AD> - Issuer: OpenIdConnect
* Type: family_name - Value: <SurName from AD> - Issuer: OpenIdConnect

I’ll setup my Okta environment to make sure you’re not missing anything between what you’ve provided and the docs. Seems like what you have done so far should work.

Thanks Adam, I look forward to your results.

To note, in the Okta app access is granted to my account and the Okta admin’s account. Once this is working, access will be granted to an AD group. I’m not sure if assigning access this way may be involved in the wonkiness, but wanted to mention it as it is something different from the docs.

Have a good one!

1 Like

I have not forgotten about this. Working on getting my Okta account enabled again. They seem to have disabled my trial and now I cannot sign up for a developer account. I will let you know as soon as I hear back from Okta support and have some more info.

No worries. I see y’all pushed PSU 2.10.0 yesterday as well as some new YouTube videos; you’re a busy man! I upgraded to the latest 2.10.0 yesterday and it did not magically start bringing over the AD Groups/Claims. I do appreciate you looking into this, when you can.

I was able to get this to work following the docs. One thing I did notice that we run through the authorization scripts twice when using Okta. We run then once when the user signs in and then another time once we receive the user information (groups). This means that if you are attempting to log the roles, it probably won’t work without a null check.

This is my working check for my admin group.

param(
[Security.ClaimsPrincipal]$User
)

$UserInfo.Groups -contains 'Admin'

This is how I logged the JSON to make sure it was being sent in there. We automatically deserialize the $UserInfoJson to $UserInfo but both variables are available.

param(
[Security.ClaimsPrincipal]$User
)

if ($UserInfo)
{
     $UserInfoJson | Out-File .\temp.json
}

$true

Hey Adam,

Thank you for walking through this and testing on your end. I’ve added [Security.ClaimsPrincipal] to my $User parameter, and setup the .json file export. I’m able to see 1 group that comes over, called “Everyone”; which is not an AD group. After working with my Okta admin for a while, we created a test Okta group (not an AD group) and joined me to it. Now I see that test Okta group coming over and I can assign roles with $UserInfo.Groups -contains ‘test Okta group’.

So, we’re getting Okta groups to come over, but not AD groups. We double checked and Okta itself can see our AD groups.

At this point the issue seems to be on the Okta side. Anyone have ideas on why Okta would bring over Okta groups, but not AD groups?

Thanks,
Rob

Hey everyone,

My Okta admin ended up making some changes that fixed this issue and pulled over the AD groups.

My PUS groups I want to bring over as claims have a naming convention. Let’s say they all start with PSU-. The settings below in Okta, along with the PSU settings posted above, are what got this working for me.

Groups claim type: Expression
Group claim expression: groups
expression: Groups.startsWith(“active_directory”, “PSU-”, 100)

1 Like