Openid authentication issues in 5.4.0 version

Product: PowerShell Universal
Version: 5.4.0

We have version 5.3.3 working correctly with authentication via openid. When updating to version 5.4.0 when booting the service and launching the application we observe the following error,

2025-03-21 06:07:47.189 +00:00 [ERR][Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware] An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Invalid response from pushed authorization: content type is not application/json.
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.GetPushedAuthorizationRequestUri(HttpResponseMessage parResponseMessage)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.PushAuthorizationRequest(OpenIdConnectMessage authorizeRequest, AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsyncInternal(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
   at PowerShellUniversal.DashboardEndpointSource.Execute(Dashboard dashboard, HttpContext httpContext) in D:\a\universal\universal\src\Universal.Server\Routing\DashboardEndpointSource.cs:line 65
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at PowerShellUniversal.FeatureMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\FeatureMiddleware.cs:line 42
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at PowerShellUniversal.DisallowedModeMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\ModeMiddleware.cs:line 35
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at PowerShellUniversal.CspMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\CspMiddleware.cs:line 28
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Universal.Server.Middleware.RoutingMiddleware.Invoke(HttpContext httpContext, IPolicyEvaluator policyEvaluator) in D:\a\universal\universal\src\Universal.Server\Middleware\RoutingMiddleware.cs:line 185
   at PowerShellUniversal.PSUMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\PowerShellMiddleware.cs:line 15
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Universal.Server.Middleware.WindowsAuthMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\WindowsAuthMiddleware.cs:line 58
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Universal.Server.Middleware.SwaggerAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in D:\a\universal\universal\src\Universal.Server\Middleware\SwaggerAuthMiddleware.cs:line 51
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at AspNetCoreRateLimit.RateLimitMiddleware`1.Invoke(HttpContext context) in D:\a\universal\universal\src\AspNetCoreRateLimit\Middleware\RateLimitMiddleware.cs:line 109
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)

How do we have openid configured? In authentication.ps1 file,

Set-PSUAuthenticationMethod -Type "OpenIDConnect" -CallbackPath "/auth/signin-oidc" -ClientId $Secret:OpenIDClient -ClientSecret $Secret:OpenIDSecret -Authority "https://xxx/oidc" -Scopes "openid profile roles" -SaveTokens $True -ResponseType code

For the time being we have reverted to version 5.3.3. Any idea of ​​the why of this behavior?

Note: The response obtained from the provider openid if in JSON format. For example,

{
  "Claims": [
    {
      "Type": "jti",
      "Value": "xxxx",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://xxxx/oidc",
      "Properties": []
    },
    {
      "Type": "sid",
      "Value": "xxxx",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://xxxx/oidc",
      "Properties": []
    },
    {
      "Type": "name",
      "Value": "pseudo Pseudo user for service availability reporting on SMART FE",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://xxxx/ims-sso/oidc",
      "Properties": []
    },
    {
      "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
      "Value": "spp",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://xxxx",
      "Properties": []
    },
    {
      "Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
      "Value": "reports",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://xxxx",
      "Properties": []
    },
    {
      "Type": "RolesAssigned",
      "Value": "true",
      "ValueType": "http://www.w3.org/2001/XMLSchema#string",
      "Issuer": "https://www.poshtools.com",
      "Properties": []
    }
  ],
  "Identity": {
    "Name": "xxx"
  }
}

Thanks!

“openid profile roles”

what happens if you use “openid profile groups”?

Thanks for the suggestion but my openid provider doesn’t support the ‘groups’ scope. That’s why we use roles.

Can you share which service you are using? 5.4 bumped the .NET version, which bumped the OIDC libraries and may be part of the problem.

Hello @adam , unfortunately I do not manage the service provider implementation. It is a CAS based internal solution: CAS - OpenID Connect Authentication.

Hello @adam, sorry for mentioning you again. So I have been able to investigate with .net 9, by default, if the provider admits it Pushed Authorization (PAR) is used as authorization method.
Checking the logs again I see that the problem is there,

"...
System.InvalidOperationException: Invalid response from pushed authorization: content type is not application/json.
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.GetPushedAuthorizationRequestUri(HttpResponseMessage parResponseMessage)
..."

# Relevant part: "...parResponseMessage..."

I’m not quite clear if the provider we use admits it or not but (and it will probably be very hard for me to find out), in any case, is there any way to change this behaviour?

In following links:

i see that it is possible to disable Pushed Authorization (PAR) but. If so, is there any way to implement it in PSU?
I have tried it with the ‘Configure’ parameter in the ‘Set-PSUAuthenticationMethod’ cmdlet trying without any success,

Set-PSUAuthenticationMethod -Type XXX -Configure {
     $options = $args[0]
     $options.PushedAuthorizationBehavior = 'Disable'
    } 
}

Thanks in advance

I’m not sure why that wouldn’t work but I do think I will need to some research into this particular provider. I opened a GitHub issue so this doesn’t get buried.

I’m going to disable this by default and we can make it configurable in a future PSU version.

Thanks @adam , version 5.4.4 installed and openid authentication works!