Custom Authentication in Blazor WebAssembly – Step-By-Step Detailed Guide
In this next part of the Blazor Blog Series, Let’s learn about implementing Custom Authentication in Blazor WebAssembly Project (Blazor.Learner). We will cover some core concepts that can get you familiar with how authentication works in Blazor Applications.
PS, This is quite a detailed Article with around 3000 words. So I suggest you to bookmark this page for future reference. Grab a drink and let’s get started!
Built-in Authentication
Microsoft Ships Blazor with Built-in Authentication that can get you started quickly. But this is not what we will be looking into today. The Built-in Approach has quite a lot of limitations. For instance, what if you already have a Blazor project and want to implement authentication? You would not be able to do so. However, here is how you can set up the out-of-the-box Authentication in Blazor WebAssembly.

The other limitations of the built-in authentication in Blazor are as follows.
- You will always have to use the Entity Framework Core – Code First Approach. This is not ideal for most developers.
- This uses the old Razor Pages, not the new Razor components.
- If you already have a database with existing users, it might be really tough to integrate this authentication.
That is why we have Custom Authentication in Blazor. Let’s begin.
Implementing Custom Authentication in Blazor WebAssembly
We will start off from where we left off in our previous Part – Blazor CRUD with Entity Framework Core – Detailed Tutorial. You can get the source code here. (blazor-blog-series-part-3 branch)
PS, The provided GitHub link takes you to the repository branch where we left off. The master is the current branch.
Login & Register Models
As usual, we need to build the model classes that would take in various authentication parameters for login and registering new users. We will create these classes in the Shared Project under the Models folder. You will need to install a package to help us with the Data Annotations. (Validations for the Models)
Install-Package System.ComponentModel.Annotations
Let’s add the Register Model, Models/RegisterRequest.cs
public class RegisterRequest { [Required] public string UserName { get; set; } [Required] public string Password { get; set; } [Required] [Compare(nameof(Password), ErrorMessage = "Passwords do not match!")] public string PasswordConfirm { get; set; } }
Now create a model for Login, Models/LoginRequest.cs
public class LoginRequest { [Required] public string UserName { get; set; } [Required] public string Password { get; set; } public bool RememberMe { get; set; } }
Finally, we will need one mode model in the Share Project that is going to hold the details of the current user. Models/CurrentUser.cs
public class CurrentUser { public bool IsAuthenticated { get; set; } public string UserName { get; set; } public Dictionary<string, string> Claims { get; set; } }
That’s all to do in the Shared Project. Now we have classes to help hold authentication parameters. In this tutorial, we will go by using Microsoft Identity. You could switch this with your own logic if needed. Let’s a mode for our User. Since this Model will inherit from IdentityUser, we will be adding it to the Server Project. But before that, let’s add the required packages to our Server Project. PS, you may want to update all your existing packages before installing new ones.
Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson
Now in the Server Project, add a new class at Models/ApplicationUser.cs
public class ApplicationUser : IdentityUser { }
Let’s modify our ApplicationDbContext class to support identity. Navigate to Data/ApplicationDBContext.cs and make the following changes.
public class ApplicationDBContext : IdentityDbContext<ApplicationUser> { public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options):base(options) { } public DbSet<Developer> Developers { get; set; } }
After that, navigate to Server/Startup.cs and make the following changes.
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDBContext>(); services.ConfigureApplicationCookie(options => { options.Cookie.HttpOnly = false; options.Events.OnRedirectToLogin = context => { context.Response.StatusCode = 401; return Task.CompletedTask; }; }); services.AddControllers().AddNewtonsoftJson(); services.AddControllersWithViews(); services.AddRazorPages(); }
We will be using Cookies for state management. You could use Session Storage as well. Do not forget to add Authentication and Authorization Middlewares to the application. Navigate to the Configure method of Startup.cs and add these lines below app.UseRouting();
app.UseAuthentication(); app.UseAuthorization();
Make sure that you add these lines in the same order. With that done, we can proceed to migrations and updating the database, so that we create the required Identity tabes.
add-migration Identity update-database
The only thing that is left to do in Server Project is to actually add the API endpoint to log in, register, log out, and get current user details. Let’s add a new Controller for this at Controllers/AuthController.cs
[Route("api/[controller]/[action]")] [ApiController] public class AuthController : ControllerBase { private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; public AuthController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager) { _userManager = userManager; _signInManager = signInManager; } }
Line #1 – For accessing the endpoints like ..api/auth/login or …api/auth/register
Line #5-11 Constructor Injection of the Identity Interfaces for signing in and creating new users etc.
No, we will add the required Action Methods. Note that these are all very basic methods. You could probably implement your logic here if needed to match your business requirement.
Login – Controller Method
[HttpPost] public async Task<IActionResult> Login(LoginRequest request) { var user = await _userManager.FindByNameAsync(request.UserName); if (user == null) return BadRequest("User does not exist"); var singInResult = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false); if (!singInResult.Succeeded) return BadRequest("Invalid password"); await _signInManager.SignInAsync(user, request.RememberMe); return Ok(); }
Register – Controller Method
[HttpPost] public async Task<IActionResult> Register(RegisterRequest parameters) { var user = new ApplicationUser(); user.UserName = parameters.UserName; var result = await _userManager.CreateAsync(user, parameters.Password); if (!result.Succeeded) return BadRequest(result.Errors.FirstOrDefault()?.Description); return await Login(new LoginRequest { UserName = parameters.UserName, Password = parameters.Password }); }
Here we are also returning a Login Model after a successful registration. This is to implement auto-login after the user registers.
Logout – Controller Method
[Authorize] [HttpPost] public async Task<IActionResult> Logout() { await _signInManager.SignOutAsync(); return Ok(); }
Get Current User – Controller Method
[HttpGet] public CurrentUser CurrentUserInfo() { return new CurrentUser { IsAuthenticated = User.Identity.IsAuthenticated, UserName = User.Identity.Name, Claims = User.Claims .ToDictionary(c => c.Type, c => c.Value) }; }
Returns the currently logged-in user with an authentication state. We will also fetch the claims that can possibly contain the Roles as well. With this, we can say that the coding needed in the Server Project is done. The only aim of the server project is to provide the data. We have built the Auth Endpoint that GETS or POSTS data from/to the Datasource.
Now, The Main Part – Authentication in Blazor WebAssembly
Firstly, there is one package that is needed to be installed on the Client Project. Let’s install it.
Install-package Microsoft.AspNetCore.Components.Authorization
As mentioned previously, we now have api endpoints to facilitate authentication stuff. Now the only task left for us is to utilize these endpoints in our Client Project, right? As usual, to access endpoints, let’s add a service and its interface. We will name them AuthService and IAuthService. So the idea is that we will access these api endpoints by using an instance of injected HTTP Client in the service class from our Client Project.
Add a new interface to the client project. Services/IAuthService.cs
public interface IAuthService { Task Login(LoginRequest loginRequest); Task Register(RegisterRequest registerRequest); Task Logout(); Task<CurrentUser> CurrentUserInfo(); }
Let’s add a concrete class and implement the previous interface. These implementations would just be using the injected HTTP client and calling the required api endpoints with POST / GET JSON methods.
public class AuthService : IAuthService { private readonly HttpClient _httpClient; public AuthService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<CurrentUser> CurrentUserInfo() { var result = await _httpClient.GetFromJsonAsync<CurrentUser>("api/auth/currentuserinfo"); return result; } public async Task Login(LoginRequest loginRequest) { var result = await _httpClient.PostAsJsonAsync("api/auth/login", loginRequest); if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync()); result.EnsureSuccessStatusCode(); } public async Task Logout() { var result = await _httpClient.PostAsync("api/auth/logout", null); result.EnsureSuccessStatusCode(); } public async Task Register(RegisterRequest registerRequest) { var result = await _httpClient.PostAsJsonAsync("api/auth/register", registerRequest); if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync()); result.EnsureSuccessStatusCode(); } }
Authentication State Provider
As the name suggests, this class provides the state of authentication of the user in Blazor Applications. AuthenticationStateProvider is an abstract class in the Authorization namespace. Blazor uses this class which would be inherited and overridden by us with custom implementation for getting the user state. This state can be from either local storage, session storage, or cookies like in our case.
Let’s start by adding the Provider class in the Services folder. Let’s name it CustomStateProvider. As mentioned, this class will inherit the AuthenticationStateProvider class.
public class CustomStateProvider : AuthenticationStateProvider { private readonly IAuthService api; private CurrentUser _currentUser; public CustomStateProvider(IAuthService api) { this.api = api; } public override Task<AuthenticationState> GetAuthenticationStateAsync() { throw new NotImplementedException(); } }
You can see that, by default we get to implement a function GetAuthenticationStateAsync. Now this function is quite important as Blazor calls this very often to check the state of authentication of the user in the application. Get the point?
Also, we will be injecting the AuthService and the CurrentUser Model into the constructor of this class. The idea behind this is that we will not be directly using the service instance in the view (Razor Components), rather we will inject the instance of CustomStateProvider into our views that would in turn access the services.
Here is the finished State Provider class. I will explain it in a bit.
public class CustomStateProvider : AuthenticationStateProvider { private readonly IAuthService api; private CurrentUser _currentUser; public CustomStateProvider(IAuthService api) { this.api = api; } public override async Task<AuthenticationState> GetAuthenticationStateAsync() { var identity = new ClaimsIdentity(); try { var userInfo = await GetCurrentUser(); if (userInfo.IsAuthenticated) { var claims = new[] { new Claim(ClaimTypes.Name, _currentUser.UserName) }.Concat(_currentUser.Claims.Select(c => new Claim(c.Key, c.Value))); identity = new ClaimsIdentity(claims, "Server authentication"); } } catch (HttpRequestException ex) { Console.WriteLine("Request failed:" + ex.ToString()); } return new AuthenticationState(new ClaimsPrincipal(identity)); } private async Task<CurrentUser> GetCurrentUser() { if (_currentUser != null && _currentUser.IsAuthenticated) return _currentUser; _currentUser = await api.CurrentUserInfo(); return _currentUser; } public async Task Logout() { await api.Logout(); _currentUser = null; NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); } public async Task Login(LoginRequest loginParameters) { await api.Login(loginParameters); NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); } public async Task Register(RegisterRequest registerParameters) { await api.Register(registerParameters); NotifyAuthenticationStateChanged(GetAuthenticationStateAsync()); } }
GetAuthenticationStateAsync – Get the current user from the service object. if the user is authenticated, we will add his/her claims to a list and create and Claims Identity. After this, we will return an Authentication State with the required data.
The other 3 Methods are pretty straightforward. We will just be calling the required service methods. But here is one extra thing that I would want to explain. Now with every log in, registration, and logout, technically there is a state change in the authentication. We need to let the entire application know that the user’s state has changed. Hence we use a Notify Method and pass the current authentication state by calling the GetAuthenticationStateAsync. Pretty logical, yeah?
Now, to activate these services and dependencies in the Client Project, we need to register them into the container yeah? For this, Navigate to the client project’s Program.cs and make the following additions.
public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("app"); builder.Services.AddOptions(); builder.Services.AddAuthorizationCore(); builder.Services.AddScoped<CustomStateProvider>(); builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<CustomStateProvider>()); builder.Services.AddScoped<IAuthService, AuthService>(); builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); await builder.Build().RunAsync(); } }
That’s done too! Now let’s work on adding the Razor Components for the UI. Here we will have to add 2 Components, i.e., the Login and the Register component. We will be protecting the entire application by securing it. That means only an authenticated user will be allowed to view any data on the page. So, we will have a separate Layout Component for the Login/Register components. Let’s add this first.
Navigate to the Shared Folder with the Client project. Here is where you would ideally add any shared Razor Components. In our case, let’s add a new Razor Component and call it, AuthLayout.razor
@inherits LayoutComponentBase <div class="main"> <div class="content px-4"> @Body </div> </div>
You can see that it is quite a basic html file with an inherited tag. We will not concentrate on CSS/HTML in this series. However, this layout component is going to act as a container that will hold the Login and Register component within itself. Feel free to do all the fancy html stuff here.
PS, If you are going to add in css styles, I suggest you to add these properties in the site.css file located at the wwwroot/css folder to keep things organized.
Login Component
Create a new Razor Component under Pages/Authentication/Login.razor
@page "/login" @layout AuthLayout @inject NavigationManager navigationManager @inject CustomStateProvider authStateProvider <h1 class="h2 font-weight-normal login-title"> Login </h1> <EditForm class="form-signin" OnValidSubmit="OnSubmit" Model="loginRequest"> <DataAnnotationsValidator /> <label for="inputUsername" class="sr-only">User Name</label> <InputText id="inputUsername" class="form-control" @bind-Value="loginRequest.UserName" autofocus placeholder="Username" /> <ValidationMessage For="@(() => loginRequest.UserName)" /> <label for="inputPassword" class="sr-only">Password</label> <InputText type="password" id="inputPassword" class="form-control" placeholder="Password" @bind-Value="loginRequest.Password" /> <ValidationMessage For="@(() => loginRequest.Password)" /> <div class="form-check m-3"> <InputCheckbox id="inputRememberMe" class="form-check-input" @bind-Value="@loginRequest.RememberMe" /> <label class="form-check-label" for="inputRememberMe">Remember Me</label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> <label class="text-danger">@error</label> <NavLink href="register"> <h6 class="font-weight-normal text-center">Create account</h6> </NavLink> </EditForm> @code{ LoginRequest loginRequest { get; set; } = new LoginRequest(); string error { get; set; } async Task OnSubmit() { error = null; try { await authStateProvider.Login(loginRequest); navigationManager.NavigateTo(""); } catch (Exception ex) { error = ex.Message; } } }
Line 1 – Page route – ../login
Line 2 – Set the Layout to the AuthLayout component
Line 4 Injects our CustomStateProvider instance.
Then we have a bunch of HTML that defines a form with username and password input.
From Line 35, We define the Model object (LoginRequest) and build the function OnSubmit that gets fired when you submit the form with valid data. Here we just use the custom state provider to access the service and ultimately the api to verify the login.
Register Component
Similarly, we create a register component too under Pages/Authentication/Register.razor
@page "/register" @layout AuthLayout @inject NavigationManager navigationManager @inject CustomStateProvider authStateProvider <h1 class="h2 font-weight-normal login-title"> Register </h1> <EditForm class="form-signin" OnValidSubmit="OnSubmit" Model="registerRequest"> <DataAnnotationsValidator /> <label for="inputUsername" class="sr-only">User Name</label> <InputText id="inputUsername" class="form-control" placeholder="Username" autofocus @bind-Value="@registerRequest.UserName" /> <ValidationMessage For="@(() => registerRequest.UserName)" /> <label for="inputPassword" class="sr-only">Password</label> <InputText type="password" id="inputPassword" class="form-control" placeholder="Password" @bind-Value="@registerRequest.Password" /> <ValidationMessage For="@(() => registerRequest.Password)" /> <label for="inputPasswordConfirm" class="sr-only">Password Confirmation</label> <InputText type="password" id="inputPasswordConfirm" class="form-control" placeholder="Password Confirmation" @bind-Value="@registerRequest.PasswordConfirm" /> <ValidationMessage For="@(() => registerRequest.PasswordConfirm)" /> <button class="btn btn-lg btn-primary btn-block" type="submit">Create account</button> <label class="text-danger">@error</label> <NavLink href="login"> <h6 class="font-weight-normal text-center">Already have an account? Click here to login</h6> </NavLink> </EditForm> @functions{ RegisterRequest registerRequest { get; set; } = new RegisterRequest(); string error { get; set; } async Task OnSubmit() { error = null; try { await authStateProvider.Register(registerRequest); navigationManager.NavigateTo(""); } catch (Exception ex) { error = ex.Message; } } }
You can see there are a bunch of unresolvable errors that probably say that a few items are not defined in the namespace or something. This is because we have not imported the new namespaces. To do this, navigate to _Import.razor and add these lines to the bottom.
@using Blazor.Learner.Client.Services @using Microsoft.AspNetCore.Components.Authorization
Now, the error will go away. Now, we need to let Blazor know that we have authentication enabled and need to pass Authorize attribute throughout the application. For this, modify the Main Component, i.e., App.razor component.
<Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <CascadingAuthenticationState> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </CascadingAuthenticationState> </NotFound> </Router>
What is AuthorizeRoteView?
It’s a combination of AuthorizeView and RouteView, so that is displays the specific page but only to users who are authorized.
What is CascadingAuthenticationState?
This provides a cascading parameter to all descendant components.
Let’s add a logout button to the top navigation of the application to allow the user to log out. We will have to make changes to the MainLayout.razor component for this.
@inherits LayoutComponentBase @inject NavigationManager navigationManager @inject CustomStateProvider authStateProvider <div class="sidebar"> <NavMenu /> </div> <div class="main"> <div class="top-row"> <button type="button" class="btn btn-link ml-md-auto" @onclick="@LogoutClick">Logout</button> </div> <div class="content px-4"> @Body </div> </div> @functions{ [CascadingParameter] Task<AuthenticationState> AuthenticationState { get; set; } protected override async Task OnParametersSetAsync() { if (!(await AuthenticationState).User.Identity.IsAuthenticated) { navigationManager.NavigateTo("/login"); } } async Task LogoutClick() { await authStateProvider.Logout(); navigationManager.NavigateTo("/login"); } }
And finally, we will need to display our username on the Index Component soon after we log in. Navigate to Pages/Index.razor and make the following changes.
@page "/" <AuthorizeView> <Authorized> <h1>Hello @context.User.Identity.Name !!</h1> <p>Welcome to Blazor Learner.</p> <SurveyPrompt Title="How is Blazor working for you?" /> </Authorized> <Authorizing> <h1>Loading ...</h1> </Authorizing> </AuthorizeView>
Let’s test our Application now.



support me
Thank you for visiting. If you like my content and code, support me by buying a couple of coffees so that I can find enough time to research & write new articles. Cheers!
Summary
In this article, we have gone in-depth into Custom Authentication in Blazor WebAssembly. I will be updating this article with more data for you to learn. I hope this covers the entire Custom Authentication in Blazor WebAssembly. Let me know if I missed out on anything. You can find the completed source code here. Share this article within your developer community so that other developers can get a taste of Blazor! Happy Coding 😀
Thank you, Dear Mukesh,
This is something great that I wanted to recommend you to publish an article about it,
I am very excited to read this article after this comment, then I will implement it, I hope you have included the custom users role management as well in this article,
I had a requirement that wanted to build a complete dynamic user management
I am going to write the following software requirement SRS, use cases for that,
There is a need to be the default super admin with full access withing application, After login,
The super admin adds the new roles into the system such as Module Admin, Editor, office manager, Normal user, and so on.
The super admin give role access privilege Read, Create, Update, Delete, to the particular controller or particular method,
The super admin create the new user account and assign to the specific role,
The public users can register by a customs form or Goole API or Facebook API authentication,
After user login, their need to be a user profile page with file upload option, to change their profile picture, and other information,
Every user when login into the system will view, read, update delete, those data, and menu, which has the role access for it, otherwise will view an Ops page or not found page,
Note: I have designed the SQL database for this, I am very excited to implement it with Blazor, I am going to read your article, if you don’t cover these features, please publish the next article to complete the dynamic user management, or add your comment here to explain how to achieve this goal,
Hello again 😀
I would suggest following these steps.
1. Seed the Role “SuperAdmin” and other roles to whichver the appropriate table is.
2. In my service layer, it’s possible to add custom logic, maybe you could load the roles to claims there. Or even create a seperate list of roles object.
Your requirement seems very similar to the user/role management of Identity. Give it a look. I will try posting this as the next part to the seris.
I was not able to include role management because this post itself was quite too long 😀 Hope you read it. How did you like it? Any suggestions?
Greetings,
Yes I have read, it was great article, you have done a lot of work here, I appreciate your efforts.
I just want to add some suggestions for the next articles of user/role management module.
I have used the Microsoft built-in Identity in my project, as you mentioned there are some limitations to implement with custom requirements like a dynamic user/role management,
As I mentioned the requirements in my first comment. In this comment I will explain the Database Tables which is needed.
I have designed a complete SQL database which includes the below tables or models class,
if we code this and implement, it will be a great custom dynamic user/role management that can be use for any application, as a user/role management module.
Database Tables or Models:
1- Controllers And Actions Table:
Id, Controller Name, Action Name, ActionType (GET or Post), Permission Name (Read,Create,Update,Delete).
Developer will insert all the Controllers and Actions in this Table during development.
2- Roles Table: Id, Role Name.
Default Super Admin will create all the system roles through a web form.
3- Role Access Table: Id, Role-Id, controllsAndActionId, bool=hasaccess.
Super Admin will assigne the role access in this table, which one role can has access to one or many Controllers and methods,
4- Users Table: Id, name, username, pass, profil picture, Role-Id and so on.
Super admin will create user account and add a specific role to it,
Or user can register from a public form as a guset role then super admin will give another’s role to the user if needed,
Some logic:
When the authorized user login into the system we will check what is his role and what is the access of his role to view, creat,update….
If user is not authorized to any specific view Page and Controllers, and try to access it, the system will display a notify or an anathurzed message to the user,
After successfully login:
User Profile Page, the authorized user can update thier infromation and profile picture.
This is what I think to build a complete dynamic user/role management module.
You might add something more to Improve it, even if we use bootstrap popup form and notify message and replace blazor with jequry ajax, it will be extra great.
There will be a lot of functionalities to cover such as dropdownlist, file upload, ajax form post and popup form, notify message and so on.
Please if you have time publish an article for this requirements, either with Blazor or ASP.Net core MVC using jequry ajax call or any other JavaScript library you recomnd.
I am sure all developers need this for thier application, I think we should buy 10 coffees, to you for this work ?
Regards
Hedayat Hoshamd
Hi, have you made the code with authorization as you expected? it’ll be very interesting. If yes have you a github link?
Hi, very nice article! I immediatly tried your github code and it works (just changed to mysql database). I tried to decouple the server asp.net from the blazor WASM client. The first run on port 5000, the client on port 6000. I added CORS, changed httpclient and the api calls works. But the authentication stop working. Is it possible that the authentication works only if the solution is hosted by asp.net server only ?
Thanks for great content!
.client and .server are both web applications. how to make this work when they are hosted on server, e.g. azure app services.
I think – await _signInManager.SignInAsync(user, request.RememberMe); is not going to work, resulting client application will always never be authenticated.
Thank you so very much, after following the Microsoft way and there useless documentation, I came across your site, and it works.
How do you Handel JWT tokens?
Hi Mukesh. Thanks for this article. Very helpful. Sorry I can’t send you a coffee but you are great.
Hi Charlie! Thanks a lot for your feedback 😀
I tried using your article to convert a Blazor WebAssembly project which had been created with the built in Authentication (RemoteAuthenticatorView) to your custom method but ran into many issues.
I’m sure this is a scenario many people will find themselves in. Would it be possible to provide advice or a guide on how to do this?
Dear Mukesh;
I implement this walk thru with Blazor WebAssembly and it works fine.
Then i tried to implement it with Balzor Server it works also good, but when i log in – with a correct user name and password) it authenticate the user but in the Mainlyaout :
protected override async Task OnParametersSetAsync()
{
try
{
if (!(await AuthenticationState).User.Identity.IsAuthenticated)
{
navigationManager.NavigateTo(“/login”);
}
}
catch (Exception ex)
{
errorString = $”There was an error: {ex.Message}”;
}
it always navigate to login page as User.Identity.IsAuthenticated always false.
Did i miss some thing that i should use with Blazor server side.
Thank you very much.
on Server
startup.cs
————–
app.UseRouting();
// must between app.UseRouting and app.UseEndpoints
app.UseAuthentication();
app.UseAuthorization();
// End
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile(“index.html”);
});
Thank you very much it works fine.
Sorry i tried that with the Wasm Blazor it works but with the Blazor server it did not work, it always returns if (!(await AuthenticationState).User.Identity.IsAuthenticated) false is it is not authenticated while the service and the controller recognize the user.
Any help please, Thank you very much.
Hey, thanks for throughout tutorial! Can I use a database-first approach instead of code-first and migrations? How much of change will there in such occasion?
Hi you project very good but if we have user with more than one roles like “Admin” and “superAdmin”
it didn’t work i tried to solve it but unfortunately I couldn’t
Great article Mukesh,
Waiting for the roles management!
Keep coding…
Thanks
Would you be willing to extend this example and show how to add Email confirmation and Forgot Password/Reset Password?
Hello Mukesh!
Thanks for all your greate articles, they have helped me with greate learing.
I wonder, i have created a Blazor Webassembly asp core hosted with individual identity (IdentitiyServer4). When trying to impliment the solution from this article, i can’t get it working. The application crashes on startup.
Error :
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: ValueFactory attempted to access the Value property of this instance.
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].CreateValue()
at System.Lazy`1[[Microsoft.Extensions.Http.ActiveHandlerTrackingEntry, Microsoft.Extensions.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Value()
at Microsoft.Extensions.Http.DefaultHttpClientFactory.CreateHandler(String name)
How about implementing with JWT token?
Which one is better between cookies and jwt token?
Thank you for sharing this blog with us its very useful for everyone.
Thank you for this article, it really helped a lot! I have a question about the login page. I have the identity working, when I look at the web developer tools, a cookie is made and everything is fine, until it goes back to loading the home page. Instead of loading the home page with the hello message, it goes back to the login screen.
Any suggestions?
Thank you!
Thank you,
I need your help, if we have many roles for a one user, it fails according to the unique key of claim dictionary.
When I changed it to List instead of dictionary, it fails too.
any suggestions?
I have solution in this time … 12/25/2021
I solve this problem.
https://stackoverflow.com/questions/68894138/problem-when-user-has-multi-roles-in-blazor-webassembly-authentication-and-autho/71777699#71777699
Hi,
First of all, thanks for this great tutorial ! it helped me a lot.
I wanted to implement Role based authorization using this tutorial Model, but can’t fin any way to do it.. Someone has an idea ?
Greetings
Rémy
Hello,
but if the user want change the password ?
Very nice article on implementing custom authentication in Blazor. Will this also work with Blazor server?
Great article Mukesh! After seeing the default auth for WASM that Microsoft provides out of the box, I immediately thought that it should be done the way you describe it in this article. I’m surprised the default isn’t exactly this
Great Job.
How do you add Authorization(Roles) to this ?
Thanks
Loved this, and it was just what I was looking for, but when using just a Blazor Server app I get an error on the log in page.
After clicking sign-in I get the error An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
It is the same when attempting to register an account too.
Any ideas, help?
Hi, thanks to this tutorial.
I tried to implement it it’s work fine except logout buton. I received the message
System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at FollowUpDash.Client.Services.AuthService.Logout() in C:\App\sbd\FollowUpDash\FollowUpDash\Client\Services\IAuthService.cs:line 36
at FollowUpDash.Client.Services.CustomStateProvider.Logout() in C:\App\sbd\FollowUpDash\FollowUpDash\Client\Services\CustomStateProvider.cs:line 41
at FollowUpDash.Client.Shared.MainLayout.LogoutClick() in C:\App\sbd\FollowUpDash\FollowUpDash\Client\Shared\MainLayout.razor:line 43
Have you an idea how to fix this?
Hey Mukesh,
thank you for the useful article.
I’d like to suggest: could you write an article about Blazor Wasm+AWS Cognito authentication?
I’m sure it will be interesting How-to
Hey! I already have that in my backlog of todo article. Will be posting it shortly. Meanwhile, you can checkout https://codewithmukesh.com/blog/securing-dotnet-webapi-with-amazon-cognito/ , where I wrote about Cognito auth in ASP.NET Core Web API. Thanks
Hi Mukesh,
Thanks for the great work! I really love your tutorials they are always simple to follow and straight to the point and mostly adhering to the best practice. I went through the blazor series and lastly to custom blazor authentication piece and it was awesome! The application worked as expected and will very much assist in building my future blazor projects. One thing I noticed while logging in to the application it first flickers to the home page or the main page then quickly to login page. I am not sure if there is something I missed out or its a bug within the application. If its a bug how do you fix it or if I am missing out on something what exactly am I missing out coz the behavior is kind of annoying. I will really appreciate your feedback otherwise keep up with the good work of sharing your knowledge with the developer community.
Thank you!