In this article, we are going to do a small demo on Blazor Server authentication and authorization using Microsoft AspNetCore Identity.
Microsoft AspNetCore Identity Library:
AspNetCore Identity:
- Built-in login functionality library that supports authentication of all different .NET applications.
- Provides rich authentication UI pages and customizable as well.
- Adoptable for External Authentication providers like 'Google', 'Facebook', 'Outlook'.
- Can be integrated with other authentication like 'IdentityServer4', 'Azure Active Directory', 'Azure Active Directory B2C(Azure AD B2C)'.
Create A .NET6 Blazor Server App With Individual Authentication:
Let's create a .Net6 Blazor Server sample application with individual authentication to accomplish our demo. We can use either Visual Studio 2022 or Visual Studio Code(using .NET CLI commands) to create any.Net6 application. For this demo, I'm using the 'Visual Studio Code'(using the .NET CLI command) editor.
CLI command
dotnet new blazorserver -o Your_Project_Name -au Individual
dotnet new blazorserver -o Your_Project_Name -au Individual
IdentityDbContext:
IdentityDbContext loads from the 'Microsoft.AspNetCore.Identity.EntityFrameworkCore'. By default 'IdentityDbContext' implemented file created into our project like 'Data/ApplicationDbContext.cs'. So the IdentityDbContext can control all our authentication tables like 'Users', 'Roles', 'Claims' etc implicitly.
Data/ApplicationDbContext.cs:
Program.cs:
Here default database is configured to 'Sqllite', but for this demo, we are going to use 'Microsoft SQL Database'. So let's install the SQL package which is an extension for the entity framework core.
Package Manager
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.1
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.1
.NET CLI Command:
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 6.0.1
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 6.0.1
Now update the 'ApplicationDbContext' registration to use the 'SQL' database and also add the connection string in the appsetting.json file.
Create Identity Tables:
Using entity framework migration we can update the database to create our tables that can be interacted by the 'IdentityDbContext'. So by default, we can observe the migration files at 'Data/Migration'. So to update the database run the below command(for running the migration files against the database).
dotnet ef database update
On running the above command any error occurs that related to migration files, then delete the existing migration files and create a new migration with the below command.
dotnet ef migrations add Your_Migration_Name_Any_Name
So to reflect migration changes in the database need to run the above-mentioned update command.Identity tables get created are like:
Now we can run and check the pages like 'Registration' and 'login'.- The 'AspNetUsers' table for to store user authentication information.
- The 'AspNetRoles' table for the roles information.
- The 'AspNetClaims' table for user-related claims.
- The 'AspNetUserTokens' table for user authentication tokens.
- The 'AspNetUserLogins' table for user associated logins.
- The 'AspNetUserRoles' table for users mapped with roles.
- The 'AspNetRoleClaims' table for roles with specified claims.
Registration Page:-
AuthenticationStateProvider:
In the Blazor server application, a built-in provider called AuthenticationStateProvider provides the authenticated user information into the Blazor Components. This AuthenticationStateProvider reads the data from the 'HttpContext.User', Since blazor components can't read the 'HttpContext' of request they depend on the AuthenticationStateProvider.
So in our project, we have an auto-generated class like 'RevalidatingIdentityAuthenticationStateProvider' that inherits the 'Microsoft.AspNetCore.Components.Server.RevalidatingServerAuthenticationStateProvider' that inherits the 'Microsoft.AspNetCore.Components.Server.ServerAuthetnicationStateProvider' that implements the 'Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider'. So from the we can understand that our 'RevlidatingIdentityAuthenticationStateProvider' is a custom implementation for our 'Microsoft.AspNetCore.components.Authorization.AuthenticationStateProvider'.
Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs:
Program.cs:
Now this 'AuthenticationStateProvider' will be used as Cascading property inside of any Blazor Component that is possible because of the 'CascadingAuthenticationState' Blazor component in the 'App.razor'.
App.razor:
The 'Microsoft.AspNetCore.Identity.UI' package is a 'Razor Class Library'. This library is bundled with all rebuild-authentication logic and the razor pages(Registration, Login, ForgotPasswor, etc razor pages).
So to load all Identity UI can be done by registering the 'DefaultIdentity' service in Program.cs file.
Program.cs:
Authentication Middleware:
In an application, authentication is enabled by registering the authentication middlewares.
Generate Identity Files For Explicit Customization:
We can customize the Identity authentication logic or UI pages by generating the files explicitly inside of the 'Area/Identity' folder. So that means generating explicit files will override the default authentication logic or pages inside of the 'Microsoft.AspNetCore.Identity.UI'(Razor class library).
So follow the steps to generate the identity UI files explicitly:-
Step 1:-
Install the 'Microsoft.VisualStudio.Web.CodeGeneration.Design' NuGet package.
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
Step 2:-
Install the dotnet scaffolder globally into your system.
dotnet tool install -g dotnet-aspnet-codegenerator
Step 3:-
Now run the identity scaffolder to generate the UI files
dotnet aspnet-codegenerator identity -dc {Your_Project_Name}.Data.ApplicationDbContext
Now after completing the above steps you observe all identity files generated as below
Authorization:
Let's implement the claims base authorization. So let's add a few claims in the 'AspNetUserClaims' table for a user.
Now create a claims-based authorization policy in the Program.cs
Program.cs:
builder.Services.AddAuthorizationCore(options => { options.AddPolicy("pageview-policy", policy => { policy.RequireClaim("ViewIndexPage","yes"); }); });
- Any component that is decorated with this policy then application only allows the users that contain the specified claim type and its value.
Pages/Counter.razor:
@attribute [Authorize(Policy ="pageview-policy")]Now if we try to access the page without authentication or without proper authorization page will show an error message as below
Support Me!
Buy Me A Coffee
PayPal Me
Video Session:
Wrapping up:
Hopefully, I think this article delivered some useful information on Blazor Server Authentication and Authorization with Microsoft AspNetCore Identity. I love to have your feedback, suggestions, and better techniques in the comment section below.
This not clear at all here:
ReplyDelete"Now update the 'ApplicationDbContext' registration to use the 'SQL' database and also add the connection string in the appsetting.json file."
Hi
DeleteBy default ApplicationDbContext service registration has 'UseSQLite'
Change it to 'UseSQLServer'
And also need to add the SQl server connection string value in app settings.json
It looks that in latest version .net core 6.0.1 old Blazor Authorization files does not work well. Also @attribute [Authorize(Roles = "admin,superuser")] is always unauthorized. Did day change that stuff?
ReplyDeleteMay be auth cookie doesn't have Roles as claims
DeleteI think asp.net core identity not adding roles as default claims into the auth cookie.
we need to customize add it
thank you all worked well for me, but i am getting a {This page isn’t workingIf the problem continues, contact the site owner.
ReplyDeleteHTTP ERROR 400} on log out, any suggestions?
Hi,
Delete400 error because Logout link is on blazor component 'LoginDisplay.razor' which is a post request to the 'LogOut.cshml'(razor page)
So here razor page expecting antiforgery token in the 'Post' request which is by default not available in the blazor components.
Solution 1:
By default Blazor server application creates with individua authentication has a custom logic in 'Areas/Identity/Pages/Account/Logout.cshtml' to supress the antiforgery token requirement , but it was override by us by generating all the page in the 'Areas' folder after running our scafolding command.
So to fix i suggest to create one more dummy project with individual authentication and from the project copy the 'Logout.cshtml' into our current project then issue gets fixed
Solution2:
Enabling the Antiforgery token into the Blazor server application, which i had explained in the below blog:
https://www.learmoreseekmore.com/2022/01/part4-blazorsrver-cookie-authentication.html