Search code examples
c#blazorrazor-pageswebassemblyauthorize

Blazor WebAssembly with server side Razor page authorize problem


I created the Blazor WebAssembly app in Visual Studio 2019 with options ASP.NET Core hosted and authentication (Individual User Accounts, Store user accounts in-app) on IdentityServer4. Program generated from Visual Studio. I did not modify anything. Everything works correctly. I'm able to log in and see the client side pages with [Authorize] attribute.

In the next step I add a new Razor Page to the server side (not on the client side) - Reports.cshtml After starting the program, I can go to the newly created page. It works fine.

Now I'm adding [Authorize] attribute to the server side Reports.cshtml page. After starting the program and loggin in, the attempt to display the Reports.cshtml page ends with an error: 401 Unauthorized

What's wrong with that?

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddIdentityServer()
        .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

    services.AddAuthentication()
        .AddIdentityServerJwt();

    services.AddControllersWithViews();
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseWebAssemblyDebugging();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseBlazorFrameworkFiles();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseIdentityServer();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        endpoints.MapFallbackToFile("index.html");
    });
}

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-BlazorAuthTest1;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
      "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
      }
    },
  "IdentityServer": {
    "Clients": {
      "BlazorAuth.Client": {
        "Profile": "IdentityServerSPA"
      }
    }
  },
"AllowedHosts": "*"
}

Thank you for your help!


Solution

  • I have solved my problem, so lets hope it solves yours...

    In your startup.cs, change the line

        services.AddAuthentication()
        .AddIdentityServerJwt();
    

    To:

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

    You may have some side effects in your API controllers if using claims as it changes the naming structure, but that is easily fixed, and if you are used to writing MVC, then it makes it more like it used to be... if that makes sense. Theres more detail about this where I posted the answer to my own question. Link to that is in my comment above.

    Hpe that works for you. Let me know. Cheers