9
votes

I would like to understand, how it is possible to set up JWT authentication for Blazor Server Side Apps?

Let me draw up an example: Let's say we have a .NET Core 3.1 Web API project. The project has its own TokenController implementation, which gives out JWT for a valid user / password combination. All other Controllers require such a token for each request.

The Middleware for validating the Authentication is configured like so:

// enabling JWT bearer scheme
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => 
    {
        options.TokenValidationParameters = new TokenValidationParameters 
        {
            // TOKEN VALIDATION PARAMETERS
        };
    });

// applying default authentication policy
services.AddMvc(o => 
{
    o.EnableEndpointRouting = false;
    var policy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
    o.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

Up until here, this is working perfectly fine.

Now I would like to add a nice Blazor Server Side UI to this project, and I just can't wrap my head around how to do the Authentication then?

According to Microsoft Docs, the Authentication for Server Side Apps is supposed to take place at establishing the SignalR connection:

Blazor Server authentication

Blazor Server apps operate over a real-time connection that's created using SignalR. Authentication in SignalR-based apps is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.

(source: https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.1&tabs=visual-studio)

Unfortunately I am not able to figure out how this works - the tutorials and tips I found are either for Client Side Blazor or use Cookie / Identity...

Any ideas?

1
I hope someone can answer this, as I've been looking for an answer as well. I know some say use localstorage... but I think with Blazor server side there should be a better option. - CF-Slayer
Its driving me mad too - theres literally nothing useful anywhere! - Robert Perry
I am also looking for this: if we protect WebApi project with own Authentication, then how Blazor Server App integrates with WebApi controllers while having its' own which is based on SignalR? - Tim

1 Answers

4
votes

I set up Blazor Server with authentication, and then added JWT auth for API. So I think it's the same thing in reverse.

Here's what I did:

In Startup.cs

ConfigureServices method (I think the order might matter, not sure):

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

// not sure if this line is required for Blazor auth
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();

services.AddAuthentication()
    .AddCookie(cfg => cfg.SlidingExpiration = true)
    .AddJwtBearer(x =>
    {
        // options
    });

For Blazor pages

// SamplePage.razor.cs
[Route("page-path")]
[Authorize]
public partial class SamplePage
{ }

// or like this in SamplePage.razor
@page "page-path"
@attribute [Authorize]

For API controller

[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class SampleController : ControllerBase
{ }

I found the content in this page very helpful in getting JWT to work after I had started with a Blazor Server-side project. https://jasonwatmore.com/post/2019/10/11/aspnet-core-3-jwt-authentication-tutorial-with-example-api