dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.64k stars 25.29k forks source link

Blazor std-alone oidc authorization not requesting prompt #21510

Closed esamk closed 3 years ago

esamk commented 3 years ago

Issue description

Blazor std-alone client with oidc authorization does not ask identityprovider to redirect user to the login page.

On the client side, the console prints this after authorization call to provider:

"info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed. These requirements were not met:
      DenyAnonymousAuthorizationRequirement: Requires an authenticated user."

On the server side, I've got an asp.net core api and identityserver4 (and mvc login/logout). The authorization call from the client is received by the server and the identityserver4 is handling it. Below is the identityserver4 output of the authorization request from the client:

IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: Showing login: User is not authenticated
IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: Changing response to LoginRequired: prompt=none was requested
IdentityServer4.Endpoints.AuthorizeEndpoint: Information: {
  "ClientId": "xxxxxx",
  "ClientName": "xxxxxxxxxxx",
  "RedirectUri": "https://localhost:44362/authentication/login-callback",
  "AllowedRedirectUris": [
    "https://localhost:44362/authentication/login-callback"
  ],
  "SubjectId": "anonymous",
  "ResponseType": "code",
  "ResponseMode": "query",
  "GrantType": "authorization_code",
  "RequestedScopes": "openid profile myapi",
  "State": "36a32042223841b18dbf4e2c5d5a01ea",
  "PromptMode": "none",
  "SessionId": "",
  "Raw": {
    "client_id": "xxxxxx",
    "redirect_uri": "https://localhost:44362/authentication/login-callback",
    "response_type": "code",
    "scope": "openid profile myapi",
    "state": "36a32042223841b18dbf4e2c5d5a01ea",
    "code_challenge": "SsUpJTjFyMnujUZd_AxX8Fou3s57LoZWsLTJpOMFFWc",
    "code_challenge_method": "S256",
    "prompt": "none",
    "response_mode": "query"
  }
}

When I make a direct api call (from browser / from postman), identityserver redirects me to the login page. So, the identityserver seems to be configured correctly.

I assume the below message from the identityserver reveals the root problem:

"IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: Changing response to LoginRequired: prompt=none was requested"

The client is not asking for prompt.

Anyway, I found no help from anywhere (docs, stackexchange, figuring out the client lib config options by myself) so maybe someone here could help me out.

So my questions are:

  1. Is it possible at all to configre the blazor oidc client to ask prompt?
  2. If not, am I misunderstanding the oidc-client or authorization flow or both and the problem is somewhere else?

configurations

Client config (program.cs):

builder.Services.AddOidcAuthentication(options =>
            {
                builder.Configuration.Bind(
                    "oidc",
                    options.ProviderOptions);
            });

The oidc config in the client appsettings.json:

{
  "oidc": {
    "Authority": "https://localhost:44380/",
    "ClientId": "xxxxxx",
    "ResponseType": "code",
    "DefaultScopes": [
      "openid",
      "profile",
      "myapi"
    ],
    "PostLogoutRedirectUri": "authentication/logout-callback",
    "RedirectUri": "authentication/login-callback"
  }
}

Identityserver client config (at the server side)
---------------------------------------------------
...
new Client
    {
            ClientId = "xxxxxx",
                ClientName = "xxxxxxxxx",
                RedirectUris = { "https://localhost:44362/authentication/login-callback"},
                AllowedCorsOrigins = {"https://localhost:44362" },
                RequireClientSecret = false,
                RequirePkce = true,
                AllowedGrantTypes = GrantTypes.Code,
                AllowedScopes = { "openid", "profile", "myapi", },
                AllowOfflineAccess = true,
                RefreshTokenUsage = TokenUsage.ReUse,
                RefreshTokenExpiration = TokenExpiration.Sliding,
                SlidingRefreshTokenLifetime = 1800  
    },
...

Software versions

Client libraries:

microsoft.aspnetcore.components.webassembly\5.0.0-rc.2.20475.17\ microsoft.aspnetcore.components.webassembly.authentication\5.0.0-rc.2.20475.17\ microsoft.aspnetcore.components.webassembly.devserver\5.0.0-rc.2.20475.17\

dotnet --info output ```console .NET SDK (reflecting any global.json): Version: 5.0.200-preview.20614.14 Commit: 863605c8c3 Runtime Environment: OS Name: Windows OS Version: 10.0.19041 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.200-preview.20614.14\ Host (useful for support): Version: 5.0.1 Commit: b02e13abab .NET SDKs installed: 1.0.0-preview2-003131 [C:\Program Files\dotnet\sdk] 1.0.0 [C:\Program Files\dotnet\sdk] 1.0.4 [C:\Program Files\dotnet\sdk] 2.0.0 [C:\Program Files\dotnet\sdk] 2.0.2 [C:\Program Files\dotnet\sdk] 2.1.201 [C:\Program Files\dotnet\sdk] 2.1.300-preview1-008174 [C:\Program Files\dotnet\sdk] 2.1.301 [C:\Program Files\dotnet\sdk] 2.1.600 [C:\Program Files\dotnet\sdk] 2.1.617 [C:\Program Files\dotnet\sdk] 2.2.105 [C:\Program Files\dotnet\sdk] 3.1.111 [C:\Program Files\dotnet\sdk] 3.1.300-preview-015135 [C:\Program Files\dotnet\sdk] 3.1.400-preview-015151 [C:\Program Files\dotnet\sdk] 5.0.100-preview.8.20417.9 [C:\Program Files\dotnet\sdk] 5.0.100-rc.1.20452.10 [C:\Program Files\dotnet\sdk] 5.0.100-rc.2.20479.15 [C:\Program Files\dotnet\sdk] 5.0.200-preview.20614.14 [C:\Program Files\dotnet\sdk] .NET runtimes installed: Microsoft.AspNetCore.All 2.1.0-preview1-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.0-preview1-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-preview.8.20414.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-rc.1.20451.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-rc.2.20475.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 1.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.0-preview1-26216-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.24 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-preview.8.20407.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-rc.1.20451.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-rc.2.20475.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-preview.8.20411.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-rc.1.20452.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-rc.2.20475.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] ```
guardrex commented 3 years ago

Hello @esamk ... Open this issue for the product unit at ...

https://github.com/dotnet/aspnetcore/issues

A couple of notes in passing tho ...

esamk commented 3 years ago

Hello @guardrex Thanks for quick response. First, sorry for posting here. Will update to latest release and open issue at product unit if update doesn't fix the issue.

To your notes:

To configure a standalone or hosted Blazor WebAssembly app to use an existing, external Identity Server instance, follow the guidance in Secure an ASP.NET Core Blazor WebAssembly standalone app with the Authentication library.

As I said in the text of the issue, my client is standalone, not hosted and the server with identitystore and the api & identityserver are totally different programs, i.e. external. So I have followed the guidance to the letter :) But now that you mentioned the documentation, I find it quite confusing that docs include the standalone and hosted versions in the same document without being explicit about it. For example, the doc that I've been reading (the standalone one) says at the beginning:

To create a new Blazor WebAssembly project with an authentication mechanism:

  1. After choosing the Blazor WebAssembly App template in the Create a new ASP.NET Core Web Application dialog, select Change under Authentication.
  2. Select Individual User Accounts with the Store user accounts in-app option to store users within the app using ASP.NET Core's Identity system.

That seems to refer a hosted client, not standalone... and frankly, that's not the only confusing thing in that doc. But never mind, I am here to find help for my problem, not criticizing the docs.

guardrex commented 3 years ago

Sorry that I misinterpreted your issue. Yes, the product unit recommends working from the Standalone topic for your scenario.

Select Individual User Accounts with the Store user accounts in-app option to store users within the app using ASP.NET Core's Identity system.

Regardless of the OIDC-compliant provider in use, the app still requires the ASP.NET Core Identity system to handle authn/z, which is added by making that selection at app creation. It doesn't mean that users will literally be stored in the app in a database.

that's not the only confusing thing in that doc

This doc is the most general of the group because it pertains to any OIDC-compliant provider. For a given provider where we can add guidance to head off problems, you'd need to list out what you find confusing that I could then address with the product unit. You can do that here/now; or just as you did, open new issues. In the future, use the This page feedback button+form at the bottom of the topic ...

Capture

I want to try and address the "store users" remark further. I agree on that confusing point. Leave this issue open. It will close when the PR merges later.

WRT the error, yes, open for the product unit. Please add a cc: @guardrex and a cross-link to this issue. I'll follow the discussion and take action on the doc if it leads to something we can call out.

esamk commented 3 years ago

@guardrex Thanks, will do.

guardrex commented 3 years ago

At the beginning of the doc reads:

To create a new Blazor WebAssembly project with an authentication mechanism:

    ...
    Select Individual User Accounts with the Store user accounts in-app option to store users within the app using ASP.NET Core's Identity system.
    ...

Since the doc is for standalone, not hosted apps, this guidance seems confusing to me since I can't remember on the top of my head exactly what packages this selection will install. Why not add a remark clarifying that this selection does not mean you have to store users in the app, it merely installs the package mentioned in the next section of the doc.

Besides, it would be much clearer if the doc would start by saying that a standalone blazor app needs the Microsoft.AspNetCore.Components.WebAssembly.Authentication package and you can either install it to an existing app OR if you're creating a new app from scratch, doing the "Select Individual User Accounts" thing will install the package for you.

guardrex commented 3 years ago

I've marked this on the UE ("user experience") tracking issue to take another look when I reach this topic (and the companion hosted scenario). Thanks again for your feedback. I'll make further improvements later and keep an eye :eye: out for info from your product unit issue for their feedback on that error. There might be a gotcha 😈 that we can call out to the readers, something incorrect, or something missing. Either you or I can open a new issue when we know more.