Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor standalone oidc authorization not requesting prompt #30068

Closed
esamk opened this issue Feb 10, 2021 · 9 comments
Closed

Blazor standalone oidc authorization not requesting prompt #30068

esamk opened this issue Feb 10, 2021 · 9 comments
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Comments

@esamk
Copy link

esamk commented Feb 10, 2021

Describe the bug

Blazor stdandalone client (with oidc & default authorization service) request includes "prompt: none" when contacting authorization endpoint.

As a consequence, identityserver4 which receives the authorization request does not redirect my client to the login page.
Instead the call returns without authenticated user and the client console reports:

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

The Identityserver4 documentation says this about the values of prompt field:

- **none** no UI will be shown during the request. If this is not possible (e.g. because the user has to sign in or consent) an error is returned

- **login** the login UI will be shown, even if the user is already signed-in and has a valid session

This behavior seems to be what happens on the server side when handling the authorization request: The server output says:

IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: Showing login: User is not authenticated
IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: **Changing response to LoginRequired: prompt=none was requested**

That implies to me, that oidc client should include "prompt": "login" into the authorization request.
I also found some blog posts which seem to suggest that some earlier versions allowed to change the prompt behavior. The current version does not seem to have that option available. At least I did not found one.

My question is, is this how the Blazor oidc authorization service is supposed to work, or is this perhaps a bug? Or have I missed something or understood oidc authorization flow completely wrong.

Other than identityserver docs, I've followed the guidance in the Secure an ASP.NET Core Blazor WebAssembly standalone app with the Authentication library

Here's my config:
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	
	},
...

Exceptions (if any)

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

Further technical details

  • ASP.NET Core 5.03
  • microsoft.aspnetcore.components.webassembly\5.03
  • microsoft.aspnetcore.components.webassembly.authentication\5.03
  • microsoft.aspnetcore.components.webassembly.devserver\5.03
  • The IDE: VS 16.9
dotnet --info output
.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.3
  Commit:  c636bbdc8a

.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.103 [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.AspNetCore.App 5.0.3 [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.NETCore.App 5.0.3 [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]
  Microsoft.WindowsDesktop.App 5.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

cc: @guardrex
#21510

@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Feb 10, 2021
@javiercn
Copy link
Member

@esamk thanks for contacting us.

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

The snippet above comes from the default authorization service which is completely unrelated to this package and doesn't have anything to do with prompt=none.

What you are likely observing is due to the fact that Blazor will try to silently authenticate the user first if possible and only fallback to a redirect afterwards. We don't offer the ability to log in through a pop up via this package if that's what you are looking for.

@javiercn javiercn added ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly question labels Feb 10, 2021
@ghost ghost added the Status: Resolved label Feb 10, 2021
@esamk
Copy link
Author

esamk commented Feb 10, 2021

@javiercn
Thanks for the reply. You've lost me. What package are you talking about?

"The snippet above comes from the default authorization service "
Yes, that's the point of the issue . That is, I am asking if the authorization service works as indented or is this a bug or am I misunderstanding something.

"What you are likely observing is due to the fact that Blazor will try to silently authenticate the user first "

Uhhh, AFAIK, that's not how oidc authorization flow is supposed to work. How Blazor (the authorization service that is) could silently authenticate user when it does not yet have any knowledge about the user? I.E no auth cookie, no tokens no nothing.

My understanding is, that after fetching the .well-known/openid-configuration, it (the oidc authorizationservice) contacts the authorization endpoint (as the responsetype is set to "code"). And that is exactly what seems to happen. The point is, in that request it should probably have set the prompt parameter to value "login" instead of "none".

That's how I understand it. I might be wrong though. That's why I am asking if this is a bug or if its about me misunderstanding something.

Please, guessing does not help me at all. If you didn't get enough information from me, please just ask and I'll do my best to describe my problem/question more clearly and/or provide more information.

@javiercn
Copy link
Member

There are two packages that we use in Blazor:

  • Microsoft.AspNetCore.Authorization that deals with the authorization and that is the one responsible for emitting that message. That message only signal that the current user is not authenticated.
  • Microsoft.AspnetCore.Components.WebAssembly.Authentication deals with authenticating the user via oidc using oidc-client.js and automatically tries to silently authenticate the user before redirecting the user to the IdP if it's not possible.

Uhhh, AFAIK, that's not how oidc authorization flow is supposed to work. How Blazor (the authorization service that is) could silently authenticate user when it does not yet have any knowledge about the user? I.E no auth cookie, no tokens no nothing.

There are multiple flows, but this is called silent refresh and essentially, it asks the IdP via a silent iframe if there is already a session established for a user, and silently authorizes him (that's what prompt=none) is for. If there is no user session on the IdP, this obviously fails and a redirect is required.

We in our authenticationservice.ts explicitly perform this by calling signinsilent on the UserManager on oidc-client.js and fallback to signinredirect if that doesn't work.

I hope this helps clarify things

@esamk
Copy link
Author

esamk commented Feb 10, 2021

@javiercn
Well it did clarify in the sense that prompt = none is indeed intentional.

However, my problem is that the user never sees the login screen.
So apparently, for some reason, the signinredirect never gets called despite signinsilent failing (returns with no session or authenticated user or what ever).

Any idea what could cause that to happen?

@ghost
Copy link

ghost commented Feb 12, 2021

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@guardrex
Copy link
Contributor

guardrex commented Feb 12, 2021

@esamk ... I've marked this discussion on my UE ("user experience" ... i.e., total doc overhaul) doc tracking issue. I'll see how the doc can be improved based on this convo when I get to it on that pass.

@esamk
Copy link
Author

esamk commented Feb 12, 2021

@guardrex Ok.

@javiercn
Even though your answer clarified the issue with prompt parameter, my real issue was not actually resolved (as per my previous post). Do you think my problem is not related to blazor side auth components? Or?

@javiercn
Copy link
Member

@esamk I think it's likely some misconfiguration with your IdP. If you create a new hosted template with individual auth you can run through the login process without issues.

@esamk
Copy link
Author

esamk commented Feb 12, 2021

@javiercn Ok. Thanks for your help.

@ghost ghost locked as resolved and limited conversation to collaborators Mar 14, 2021
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved
Projects
None yet
Development

No branches or pull requests

4 participants