How do I secure a static client blazor app with Azure functions backend?

Viewed 558

So, I wanted to learn a bit about the whole serverless and static web app topic going on right now.

My plan is to create a C# client-side blazor application which is hosted as a static website, with C# Azure Functions doing the backend work. So far so good. Dealing with the code for all my functionalities seems to be just as straightforward as it could be.

Authentication on the other side is a whole different thing to tackle. I'm a bit lost when it comes to how to actually properly secure my application, and only allow people in after doing a login.

However, after doing a bit of reading as to how to do security, I have some questions still unanswered.

  1. How do I do authentication and security within my application? I was reading up on the following article: https://docs.microsoft.com/de-de/archive/blogs/stuartleeks/azure-functions-and-app-service-authentication which explains how to do security within the scope of authentication providers like Facebook, Google etc. However, coming from an Asp.Net Identity background, how can I actually use my custom identity setup? E.g, I want to provide a way to register and login in my client side blazor application, and I was hoping I could find something Identity-like here, which takes care of user management etc.

  2. In case I properly get the authentication part done, how should my client application behave to reflect the logged in state? Given there is no server behind, I can't just have something like a MVC controller handing out either the "logon" view or the "logged in" view, depending on the auth state of the client.

It would be great if someone could give me a bit of guidance here.

1 Answers

This is a bit too broad for StackOverflow, but let me break this problem down differently and explain how you can do this.

You have three main requirements here:

  1. Manage users (login, register, etc)
  2. In the server side, determine if a user is logged in.
  3. In the client side, determine if a user is logged in.

So let's see what to do in each case.

Manage users (login, register, etc)

The first thing you have to keep in mind is that ASP.NET Core Identity does not require you to use the Razor Pages UI it comes with. You don't even have to use anything from what gets originally scaffolded. There's nothing that prevents you from having a function/event/endpoint/etc to which you pass username/password and authenticate a user. Same with registering and the rest of the Identity framework.
If you don't want to reinvent the wheel, and you most certainly shouldn't since this is a security framework, you can use ASP.NET Core Identity.

In the server side, determine if a user is logged in.

There are multiple ways of doing this. Since your client is a web-based one, you can decide between tokens (for example, JSON Web Tokens (JTW)) and cookies. However, since you are working on an SPA, the recommendation nowadays is to use JWTs. You have at least two ways of achieving this:

  1. You can generate tokens on your own, using packages provided by Microsoft, and validate them with Microsoft.AspNetCore.Authentication.JwtBearer,
  2. If you think you will later on add more clients, like a mobile application, you may want to investigate giving IdentityServer a chance. There's a new package that abstracts away most of IdentityServer4 in a template using ASP.NET Core Identity. This might be overkill if you only plan on having the single Blazor app, though.

There's obviously third-party frameworks you can also look at, but before considering them, you need to make sure their code has been properly validated from a security point of view.

In the client side, determine if a user is logged in.

I cannot give you too much information on this part because I haven't worked with Blazor. However, there's most likely some authorization attribute or a way to authorize given routes, like it can be done in Angular and React. I'd suggest you to look here: ASP.NET Core Blazor authentication and authorization.
The main point to keep in mind is that your login endpoint will return the client the JWT generated (a mix of the first 2 points), and you can easily see the values of the JWT (like the username) in the client.

Related