Building a Blazor Web App with .Net 8 Cookie Authentication without Identity (InteractiveServerRenderMode)
Image by Shuree - hkhazo.biz.id

Building a Blazor Web App with .Net 8 Cookie Authentication without Identity (InteractiveServerRenderMode)

Posted on

Welcome to this comprehensive guide on building a Blazor web app with .Net 8 cookie authentication without Identity, utilizing the InteractiveServerRenderMode. In this article, we’ll delve into the world of Blazor and explore how to implement cookie-based authentication without relying on the Identity framework.

Prerequisites

Before we dive into the implementation, make sure you have the following installed on your machine:

  • .Net 8 SDK
  • Visual Studio 2022 (or later)
  • Blazor WebAssembly template

Creating a new Blazor Web App

Let’s start by creating a new Blazor Web App project in Visual Studio:

  1. Open Visual Studio 2022 and create a new project.
  2. Select "Blazor App" under the ".NET Core" section.
  3. Choose "Blazor WebAssembly App" and click "Next".
  4. Name your project (e.g., "BlazorCookieAuth") and click "Create".

In this section, we’ll enable cookie authentication without Identity. We’ll create a custom authentication handler and configure the authentication services.

Open the `Startup.cs` file and add the following code:

  using Microsoft.AspNetCore.Authentication.Cookies;
  using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.DependencyInjection;

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
      .AddCookie(options =>
      {
        options.LoginPath = "/login";
        options.LogoutPath = "/logout";
        options.AccessDeniedPath = "/accessdenied";
      });
  }

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
      endpoints.MapDefaultControllerRoute();
    });
  }

Creating a Custom Authentication Handler

We’ll create a custom authentication handler to validate user credentials and issue cookies. Create a new file called `CustomAuthHandler.cs`:

  using Microsoft.AspNetCore.Authentication;
  using Microsoft.AspNetCore.Authentication.Cookies;
  using Microsoft.AspNetCore.Http;
  using System.Security.Claims;
  using System.Threading.Tasks;

  public class CustomAuthHandler : IAuthenticationHandler
  {
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CustomAuthHandler(IHttpContextAccessor httpContextAccessor)
    {
      _httpContextAccessor = httpContextAccessor;
    }

    public async Task AuthenticateAsync(AuthenticationScheme scheme)
    {
      var context = _httpContextAccessor.HttpContext;
      var username = context.Request.Form["username"];
      var password = context.Request.Form["password"];

      // Validate user credentials (e.g., against a database)
      if (IsValidUser(username, password))
      {
        var claims = new[] { new Claim(ClaimTypes.Name, username) };
        var identity = new ClaimsIdentity(claims, scheme.Name);
        var principal = new ClaimsPrincipal(identity);

        await context.SignInAsync(principal);
      }
      else
      {
        await context.ChallengeAsync(scheme.Name);
      }
    }

    public async Task ChallengeAsync(AuthenticationProperties properties)
    {
      await _httpContextAccessor.HttpContext.ChallengeAsync(properties);
    }

    public async Task ForbidAsync(AuthenticationProperties properties)
    {
      await _httpContextAccessor.HttpContext.ForbidAsync(properties);
    }

    private bool IsValidUser(string username, string password)
    {
      // TO DO: Implement user credential validation logic
      return true; // Replace with actual validation logic
    }
  }

Implementing Login and Logout functionality

Create a new Razor component called `Login.razor`:

  @page "/login"
  @using Microsoft.AspNetCore.Authentication

  

Login



@code { [CascadingParameter] private Task authenticationStateTask { get; set; } async Task SubmitAsync() { var authenticationState = await authenticationStateTask; var scheme = authenticationState.AuthenticationScheme; await HttpContext.Authentication.ChallengeAsync(scheme); } }

Create a new Razor component called `Logout.razor`:

  @page "/logout"
  @using Microsoft.AspNetCore.Authentication

  

Logout

@code { [CascadingParameter] private Task authenticationStateTask { get; set; } async Task SubmitAsync() { var authenticationState = await authenticationStateTask; var scheme = authenticationState.AuthenticationScheme; await HttpContext.SignOutAsync(scheme); } }

Securing Routes with Authentication

We’ll secure the `/protected` route by requiring authentication. Open the `App.razor` file and add the following code:

  
    
      
    
    
      
        
      
    
  

  @code {
    [Authorize]
    protected override async Task OnInitializedAsync()
    {
      await base.OnInitializedAsync();
    }
  }

Create a new Razor component called `Protected.razor`:

  @page "/protected"
  @attribute [Authorize]

  

Protected Content

This content is only accessible to authenticated users.

We’ll enable InteractiveServerRenderMode to allow for server-side rendering of our Blazor app. Open the `Program.cs` file and add the following code:

  using Microsoft.AspNetCore.Components.Web;
  using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

  public class Program
  {
    public static async Task Main(string[] args)
    {
      var builder = WebAssemblyHostBuilder.CreateDefault(args);
      builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
          options.LoginPath = "/login";
          options.LogoutPath = "/logout";
          options.AccessDeniedPath = "/accessdenied";
        });

      builder.RootComponents.Add("#app");
      builder.Services.AddScoped();

      await builder.Build().RunAsync();
    }
  }

Now, let’s enable InteractiveServerRenderMode in the `index.html` file:

  
  

  

Conclusion

In this article, we’ve successfully built a Blazor web app with .Net 8 cookie authentication without Identity, utilizing the InteractiveServerRenderMode. We’ve implemented custom authentication handling, login and logout functionality, and secured routes using authentication.

This comprehensive guide should provide a solid foundation for building secure Blazor web apps with cookie-based authentication. Remember to replace the placeholder validation logic in the `CustomAuthHandler` with your actual user credential validation logic.

Keyword Description
Blazor Web App A web application built using the Blazor framework
.Net 8 The latest version of the .NET Framework
Cookies A small text file stored on the client-side, used for authentication
Identity A built-in ASP.NET Core framework for authentication and authorization
InteractiveServerRenderMode A feature that enables server-side rendering of Blazor components

By following this guide, you should now have a solid understanding of how to implement cookie-based authentication in a Blazor web app without relying on the Identity framework, utilizing the InteractiveServerRenderMode. Happy coding!

Frequently Asked Question

Get answers to your burning questions about Blazor Web App .Net 8 Cookie Authentication without Identity (InteractiveServerRenderMode)!

What is the main difference between Cookie Authentication and Identity Authentication in Blazor?

The main difference lies in their architecture and functionality. Cookie Authentication is a lightweight, built-in authentication mechanism in .NET Core, whereas Identity Authentication is a more comprehensive, flexible, and scalable framework that provides a lot more features, such as user management, role management, and password management. In Cookie Authentication, the authentication state is stored in a cookie, whereas in Identity Authentication, it’s stored in a database.

How do I implement Cookie Authentication in a Blazor Web App using .NET 8?

To implement Cookie Authentication in a Blazor Web App using .NET 8, you’ll need to add the `Microsoft.AspNetCore.Authentication.Cookies` package to your project. Then, in the `Startup.cs` file, add the `services.AddAuthentication()` method and configure it to use cookies. Finally, in your Razor component, use the `@inject AuthenticationStateProvider` directive to get the authentication state and authenticate users.

Why do I need to use InteractiveServerRenderMode in my Blazor Web App for Cookie Authentication to work?

InteractiveServerRenderMode is required for Cookie Authentication to work in a Blazor Web App because it enables server-side rendering, which is necessary for the authentication cookie to be set and validated. Without it, the cookie won’t be sent to the server, and authentication won’t work as expected.

Can I use Cookie Authentication with Web APIs in a Blazor Web App?

Yes, you can use Cookie Authentication with Web APIs in a Blazor Web App. When a user authenticates, the authentication cookie is sent to the server with each request, including API requests. The API can then validate the cookie and authenticate the user. This provides a seamless authentication experience for users interacting with your Web API.

How do I handle logout in a Blazor Web App using Cookie Authentication?

To handle logout in a Blazor Web App using Cookie Authentication, you can use the `SignInManager.SignOutAsync()` method to remove the authentication cookie from the user’s browser. Then, redirect the user to a login page or a page that doesn’t require authentication. This ensures that the user is effectively logged out and can no longer access restricted resources.