.Net Core 3, Blazor + Mvc And Authentication

Ashke98
12 min readDec 7, 2019

Todo Application Beside Login/Register Via Roles Inside Blazor And Mvc Application (Server Side)

Photo by Ashke98

ASP.NET Core is a modular framework that runs on both the full .NET Framework, on Windows, and the cross-platform .NET Core.

Blazor is a web framework that enables running .NET Core in the browser and It’s not experimental no more. It’s writing c# in front-end rather than javascript. Of course, still, there are some situations we need to rely on javascript, but not so much.

If you are a javascript lover you may not like Blazor, but any back-end programmer feels benefits of it.

You can read more about Blazor on Microsoft’s documentation.

Microsoft has recently released .NET Core 3 and it’s previewing .NET Core 3.1, for this tutorial I’m gonna use .NET Core 3 version.

Start Tutorial By Creating Projects

  1. First of all, get sure you have installed Visual Studio 2019 or if you have already installed get sure you’ve updated it. we will install two projects inside Visual Studio which satisfice this tutorial. So let’s check the image below the red-bordered area are the two projects we gonna create now.
Image by ashke98

1 for ASP.NET Core Web Application, name it Todo.Server

Setup configuration (notice: red-lines):

Image by ashke98

and

1 for Blazor you can right-click on the solution and add a new project, name it Todo.Client

Setup configuration (notice: red-lines):

Image by ashke98

DataBase And Models

Before get in deep in projects, we must set a new database and add tables we need so we can save user info besides the user’s tasks. Tables we will use are too simple:

  1. User (Id, UserName, Name, Surname, Password, RoleName)
  2. Tasks (Id, Title, UserId)

I’m gonna use SQL Server Management Studio to store database but you can use whatever you desire. I set the database name TodoTask, after adding tables connect the Task table to the User table via foreign key userId inside the Task table, the schema will be like the below image.

Image by ashke98

So now our database is ready, as you see we are doing a database-first approach. We need to connect the database to the project and make models. To do it, I suggest you do the reverse engineering process. There is Youtube video explaining this, follow that for database connection:

This video explains how to do reverse engineering database just be careful: video uses Class Library (.NET Standard),

You choose Class Library (.Net Core) instead

Click Here To Watch

Note: If the video was not helpful just search for EF Core Reverse Engineering, plenty of documentation you will find.

At the end of the video, you will have a third project called Todo.Data besides that EF Core 3 will be installed while reversing if not install it manually on all projects Task.Data, Task.Server and Task.Client . The DataContext to connect to the database will be TodoTaskContext either.

Inside Todo.Data must like the image below:

Image by ashke98

The resulting view of the project after proceeding all these steps will be this (A solution with 3 projects) :

Image by ashke98

Dependencies, Services, and Packages

The first part of adding dependencies is in Todo.Server and Todo.Client on Dependencies section right-click and select add reference, then choose and add Todo.Data on both projects.

Now It’s time to add other dependencies we need for both projects. First, we will handle the user’s authentication containing (Register, Login, User Claims and User Disconnection).

Startup.cs inside Todo.Server must have these services:

  1. AddDbContext service for database connection
  2. AddAuthentication service for AuthenticationScheme
  3. AddServerSideBlazor service for use Blazor inside MVC .NET Application
  4. AddControllersWithViews service application itself
  5. AddRazorPages service for connecting and use pages from Blazor inside MVC .NET Application

ConfigureServices and Configure methods must like below code:

Todo.Server Startup.cs

gist from ashke98

In method ConfigureServices, we add DbContext via AddDbContext<TodotaskContext> beside that connection string is provided by Configuration[“ConnectionStrings:TodoDb”] so we need set a environment variable called ConnectionStrings:TodoDb. To do that find a file called appsettings.json in solution and update the content as below:

TodoDb is the connection string used to connect database:

Data Source is your SQL server Instance Name

Initial Catalog is your Db Name

As you see in Configure method there two lines of code which enables user authentication:

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

and endpoints are written on a mode that we can route normal MVC .NET Application and Blazor:

MVC .NET Route:

endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");

Blazor Route:

endpoints.MapBlazorHub();endpoints.MapFallbackToPage("/_Host");

Now we are ready to make user authentication. First, we need to create a Helper that can help us to save user’s claims data, set authentication schema and Persistent Properties.

Create a folder and name it Methods, add c# class AuthMethod.cs in it. copy and paste below code inside it, load necessary using libraries via Quick Actions (Alt + Enter) to solve errors.

gist from ashke98

Then create a Controller called AccountController in Todo.Server. Inside AccountController add to methods Login and Register, one Get type method and Post type method for each.

Code inside AccountController will be like below:

gist from ashke98

If you check the Login Post method you see we have used HttpContext.SignInAsync to authorize the user. SignInAsync is a prebuilt authentication extension method in .NET Core. It takes 3 arguments AuthenticationScheme, ClaimsPrincipal and Authentication Properties.

with these arguments, it handles cookie creation that we’ll check it in the browser later. In ClaimsPrincipal we sent 3 arguments either:

  1. A username which user will enter it in the login page
  2. UserId which we will need it in some cases
  3. User role to manage allowed actions

Back-End code is ready to authorize user, it’s time to prepare front-end.

Add a new layout called _Layout.cshtml (if not exists) in the shared folder and customize it via copy-pasting below code in it:

gist from ashke98

Add View on Login and Register methods in AccountController, after creating 2 views, add codes below for each. Layout in login and register page will be _Layout.cshtml we created before.

Login.cshtml

Register.cshtml

Now our project is ready to do authorization and authentication, but if we try to run it az the first page we may face a not found page because of Blazor Route added in Startup.cs, So now it’s time to handle the Blazor side for our project.

The first matter you must know is that our main project is Todo.Server, it means every other project must be connected to this project and we just run this project.

Blazor project (Todo.Client) will be added to Todo.Server and we will have a Blazor app inside an MVC .NET Core project. To do this in Todo.Server project right-click on dependencies and add reference Todo.Client app in it, after that in Todo.Server will be 2 projects Todo.Data and Todo.Client.

Now root URL will show Blazor side (Todo.Client) if we simply run the project:

Root Url (port on your project might be something else)

Image by ashke98

The problem is none of the styles and js functions are readable from Todo.Client by Todo.Server, to solve this issue just move and replace all files inside wwwroot from Todo.Client to wwwroot of Todo.Server.

After running Todo.Server project root URL will page below page:

Image by ashke98

It’s too cool, isn’t it? We are using Blazor inside an MVC .NET Core app now.

Note: In the Counter part, Click me will work but in the Fetch data part, you will get an error because of unknows service.

Our app is ready to test authentication and create tasks functionality now.

To test the Login/Register part, we will ask user authentication to give access to the root URL (Blazor Side), It means if the user does not have access, it will be redirected to the login page when application starts, otherwise show Blazor Side. For this purpose, we must check the user’s authentication in Blazor Side and set it.

Inside Todo.Client in Shared folder add a new razor component called RedirectToLogin.razor and add code below inside it:

gist from ashke98

This code says in any part of the app you put this component it will redirect to the login page.

Now we will add code to check if the user is logged in or not. Open App.razor inside Todo.Client and replace code below instead of it:

gist from ashke98

If you build and run Todo.Server app, It will automatically redirect you to the login page, but how it does it?

App.razor is the main component of the Blazor, It handles the starting point of the components as the actual root component, So it’s logical we check user’s authentication in starting point via CascadingAuthenticationState which is prebuilt component to get the authentication state. Inside the router after the user’s searching route found we check if the user is Authorized then go to the MainLayout component otherwise we call the RedirectToLogin component.

Now run the project then the login page will appear:

Image by ashke98

It’s time to test login and register, first register two new users with different roles(one Admin, one User) inside the register page.

Then try to log in and (Holley) it will redirect to the Blazor home page.

Inside AccountController there is an action to logout user with route “/logout” inside MainLayout.razor change About link to below:

<a href="/logout" >Log Out</a>

Via this link user can log out either.

User Authentication is done, now it’s time to handle user’s access by authorizing role of it. we created two users one with Admin role and one normal User role. Each gonna have different tasks.

We are going to use admin to create tasks. From now we will write Blazor:

AuthenticationStateProvider And User Identity

If you check out _Layout page in Todo.Server we use to see if the user logged in or not, but how this will work in Blazor, what is the way to get the user’s role or username and other data?

AuthenticationStateProvider does this job for us, it is a built-in service that obtains authentication state data from ASP.NET Core’s HttpContext.User.

Inside Todo.Client, Pages folder replace blew code for index.razor:

gist from ashke98

By injecting AuthenticationStateProvider and calling GetAuthenticationStateAsync we access the user state.

Now login with both users and user’s username and role can be seen in index.razor. Below image is after I logged with my User role account:

Image by ashke98

For Part 1 the last thing we need to do is make Fetch data to work, for that simply copy below code from Todo.Client Startup.cs to Todo.Server Startup.cs as a service:

services.AddSingleton<WeatherForecastService>();

Now Fetch data is working:

Image by ashke98

For part one let’s check what we have done so far:

1. We created Blazor inside MVC .NET Core project

2. We did user authentication from MVC .Net to Blazor app

3. We could get user state in both Blazor and MVC .Net Core

4. We learned how to make components from Blazor work in MVC .Net Core app.

Part 2

Let’s create a tab for task management. At this tab admin can add and assign tasks, besides that normal user who is tasks assigned will change the status of them if they have done the process on them.

Go to MainLayout.razor under links add a new tab and call it tasks.razor by copying the code below:

<li class=”nav-item px-3">    <NavLink class=”nav-link” href=”tasks”>       <span class=”oi oi-task” aria-hidden=”true”></span> Tasks    </NavLink></li>

If you notice at href part we wrote “/tasks”, we don’t have this route. In Blazor, routes are being set inside Blazor components so we don’t need to worry about this, we can handle this when we create our desired component.

It’s time to create our first Blazor component, to do so right_click on Pages folder then add a new Razor Component like image below:

Image by ashke98

Add two components and name them :
A. Tasks.razor
B. AddTask.razor

Open Tasks. Razor then add route of this page as below code shows at top of the page:

@page "/tasks"

Now where ever of the application you this route it redirects to this page.

The contents of this page differ for admin and normal users. In order to separate we must check the authenticated user’s role.

auth.User.IsInRole("Admin")

This code tells us the role. We put it inside if clause and it’s divided into two parts.

Now the question where is the data coming from! Tasks will be fetched from the database?
If the role is admin all tasks
Else if the role is normal user tasks were assigned to logged user

You can use API for data communication from the database, but Blazor had done too easy that we don’t need it. We can write simple c# functions and use them like service instead!

There must be a folder called Services in TodoTask.Client application, add two new c# class inside it, call them Task Service.cs and UserService.cs. Before adding methods for data communication let’s register this classess as a service. For both Todotask.Server and Todotask.Client inside startup.cs add code below:

services.AddScoped<TaskService>();services.AddScoped<UserService>();

After registration as a service let’s add some functions.
Inside TaskService.cs copy and paste code below:

TaskService.cs

gist from ashke98

UserService.cs

gist from ashke98

There are 3 functions here that we can get tasks list, assign new tasks and update their status. In order to use these methods inside a Blazor component, you need to inject it as a service.

Injection can be done by this code, paste this code after the place you defined route:

@inject Todo.Client.Data.TaskService TaskService

So now we can use the methods but not everywhere.
Blazor components has a section for this purpose called code. the code section is that place we can write back-end logic we need.
Copy below code at the end of the Tasks.razor.
As you see there is a list from task type fetching tasks from the method we recently defined in TaskService.cs.

We need to care for a too important matter which is a component lifetime. We don’t know when our task list request will retrieve but we know when is the right time to ask data. Simply it is the time when component renders at first so if you check the code below we have called tasks list inside on Render component.

As we don’t know when data will arrive inside role checking clauses we add another if to wait for data coming. Blazor handles UI change itself like state change in React which is fantastic.

Total code of Tasks.razor page:

If you run the application and login with 2 different user roles there won’t be so much different because we have not assigned any task. So we will come back here after doing the AddTask.razor page.

Like Tasks.razor open Task.razor page add route at the top of the page as “/addtask”. Inject TaskService then open code section at the bottom.
We have got TaskService so we can add a new instance of a task model from service. This instance can be a new task from DB.

Our task object is ready now copy and paste below code top of the code section, by this code we can create the desired task.

@code {Todo.Data.Task task = new Todo.Data.Task();List<Todo.Data.User> users;  protected override async System.Threading.Tasks.Task    OnInitializedAsync()  {     task = new Todo.Data.Task();     users = await UserService.GetAll();  }  protected async Task Insert()  {     await TaskService.Add(task);     Navigation.NavigateTo("/tasks", true);   }}

Just care that we authorized this page just for admin via this code:

Inside Tasks.razor:

@if (auth.User.IsInRole("Admin")){<a href="addtask" class="btn btn-primary mb-3"> Add New</a>}

And inside AddTask.razor:

@attribute [Authorize(Roles = "Admin")]

It’s just admin who can add tasks.

Normal users just update the status of the task inside Tasks.razor.

Total code of AddTask.razor page:

gist from github.com/ashke98

Now congratulations if you have come so far until here, run the application then you must have your app working like gif below:

gif by ashke98

At the end of this tutorial, it’s better for you to just imagine what other things you can do in Blazor, more creative and useful. Good Luck

For Part two what we have done:

We learned how to add new components to Blazor

Our Admin user can add new tasks for users

Users can change status of the tasks

You can access the project files via this link.

--

--

Ashke98

Full Stack Software Engineer | Passionate Programmer | Someone who finds and implements ideas on new frameworks