Home > Net >  User.Claims is empty for every page outside of Areas/Identity
User.Claims is empty for every page outside of Areas/Identity

Time:07-18

Authorization doesn't work on Razor pages outside of Areas/Identity, cannot figure out why:

Steps to reproduce:

  • Fresh app. ASP.NET Core Blazor WASM Hosted

  • Create page: Areas/Identity/Index2.cshtml

  • Create page: Areas/NewArea/NewPage.cshtml

  • Register and Log in.

  • Access Index2 and NewPage and break in OnGet method while debugging.

    • Index2: property User.Claims contains multiple claims.
    • NewPage: property User.Claims is empty

Why the authorization is not "propagated" into NewPage?

When I set @page "/Identity/NewPage" it works so it is somehow related to Identity Area (??).

EDITS:

(Placing page into Pages folder of the server project results the same (no auth))

Reason why do I care: For quick loading speed I want my index page (Index.cshtml) to be razor page (not Blazor wasm). I need to display login status on index page.

More research: I have found exactly the same (unresolved, but closed) issue in aspnetcore repo. https://github.com/dotnet/aspnetcore/issues/34080

This issue describe the same scenario I have: Authorise normal Razor Pages in a Blazor WebAssemby App? and there is also a solution:

services.AddAuthentication(options =>
{
   options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
})

But I still don't understand why is this happening.

CodePudding user response:

which I am not sure if it is way to go

As I've previously mentioned, you can either use cookies authentication or Jwt authentication in order to access the ClaimsPrincipal from the Server project. The solution proposed is fine, and it is used to configure the cookies middleware used by the identity system. Incidentally, it should be:

services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
                options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
            }).AddIdentityServerJwt();

But I still don't understand why is this happening

Do you mean why the code above works ?

The code above works because it configures the cookies middleware to authenticate the user, tells the Identity System what scheme to use, and how to challenge the user. Understand this, the Server side of your app is not authenticated, unless you configure it to perform authentication, which differs from the authentication performed when you are re-directed from the WebAssembly Blazor App. I'll try to clarify this by giving you this example:

If you created a Blazor Server App with individual accounts, and then added client SignalR to enable a chat system in your app, and you want to secure your hub object with the Authorize attribute, an authenticated user to your Blazor Server App won't be able to access secured end points on the hub, unless he is authenticated on the hub as well. How to authenticate the user ? Simply by passing the application cookie to the hub. This is more or less simialr to the issue under discussion; that is, though the Identity folder and its content are authenticated (and authorized), the hosting Server App is not.

Note: Its hard to internalized this on first shot, but rest assured that the proposed code not only works but is also 100% kosher.

  • Related