Override Controller in Blazor with Azure AD B2C Authentication
Tags: webdev, dotnet, csharp
Published: 2020-01-13 11:52:43

---
title: Override Controller in Blazor with Azure AD B2C Authentication
published: true
tags: webdev, dotnet, csharp
canonical_url: https://wellsb.com/csharp/aspnet/blazor-azure-ad-b2c-custom-url/
---

[Source](https://wellsb.com/csharp/aspnet/blazor-azure-ad-b2c-custom-url/)

In this tutorial, you will learn how to override AccountController.cs in server-side Blazor so you can set a custom SignedOut URL when using Azure AD B2C authentication. If you have created a Blazor app with Azure AD B2C authentication, it was likely scaffolded using the helpful [AzureADB2C.UI](https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.AzureADB2C.UI/) package. Unfortunately, since this is now included as a class library .dll, it takes a little effort to customize the routes.

By default, your auth-enabled Blazor web app will use routes such as `AzureADB2C/Account/SignIn`. Moreover, when a user logs out, they are taken to an unbranded page located at `/AzureADB2C/Account/SignedOut`. Both of these are hard-coded into the AzureADB2C.UI package’s **AccountController.cs** ([see source code](https://github.com/dotnet/aspnetcore/blob/master/src/Azure/AzureAD/Authentication.AzureADB2C.UI/src/Areas/AzureADB2C/Controllers/AccountController.cs)), but neither provide for a great user experience in a public-facing web app.

## Disable existing Account Controller

To override the Account controller, you must first disable the existing **AccountController**. To do this, create a new class file in the root of your Blazor project and call it **B2CExtensions.cs**. Then, create a method to remove AzureADB2C.UI’s Account controller feature provider from the list of controller feature providers. The entire class might look like the following.

```csharp
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
 
namespace BlazorAzureADB2C
{
    public static class B2CExtensions
    {
        public static IMvcBuilder RemoveADB2CAccountController(this IMvcBuilder builder)
        {
            var ADB2CAccountController = builder.PartManager.FeatureProviders.FirstOrDefault(fp => fp.ToString()
                .Equals("Microsoft.AspNetCore.Authentication.AzureADB2C.UI.AzureADB2CAccountControllerFeatureProvider"));
            if (ADB2CAccountController != null)
            {
                builder.PartManager.FeatureProviders.Remove(ADB2CAccountController);
            }
            return builder;
        }
    }
}
```

The `RemoveADB2CAccountController()` method allows your app to avoid loading the default Account controller feature from the assembly. There is no need to also remove the compiled views provided by the Nuget package, because you can still use those with your custom controller.

Next, in your Blazor project’s **Startup.cs** file, invoke the method you just created. Within the `ConfigureServices()` block, you can simply chain it onto the `AddRazorPages()` call.

```csharp
services.AddRazorPages()
    .RemoveADB2CAccountController();
```

Depending on your project’s configuration, you could also chain the `RemoveADB2CAccountController()` call onto the `AddMvc()` or `AddControllers()` methods.

## Customize AccountController.cs

Now it is time to create the new Account controller. Start by creating a **Controllers** folder in your Blazor project, and add a new **AccountController.cs** class. Feel free to use the [source code for the existing controller](https://github.com/dotnet/aspnetcore/blob/master/src/Azure/AzureAD/Authentication.AzureADB2C.UI/src/Areas/AzureADB2C/Controllers/AccountController.cs) as a guide.

I wanted my new controller to be able to use the options I set up when configuring the project to use my Azure AD B2C tenant, so I included the package’s namespace.

```csharp
using Microsoft.AspNetCore.Authentication.AzureADB2C.UI;

```

Next, I did not like AzureADB2C included in the URL for my application’s user flows, such as sign-in and sign-out, so I changed the route. The previous code is commented out in the example below.

```csharp
namespace BlazorAzureADB2C.Controllers
{
    //[NonController]
    //[Area("AzureADB2C")]
    //[Route("[area]/[controller]/[action]")]
	[AllowAnonymous]
    [Route("[controller]/[action]")]
    public class AccountController : Controller
    {
		...
	}
}
```

Now, the sign-in action will appear at `Account/SignIn` instead of `AzureADB2C/Account/SignIn`. Don’t forget to also update the links in **Shared/LoginDisplay.razor**.

Finally, I wanted users to be redirected to the home page upon successful sign-out instead of loading `/AzureADB2C/Account/SignedOut`. My new `SignOut` action looks like the following:

```csharp
[HttpGet("{scheme?}")]
public async Task<IActionResult> SignOut([FromRoute] string scheme)
{
    scheme = scheme ?? AzureADB2CDefaults.AuthenticationScheme;
    var authenticated = await HttpContext.AuthenticateAsync(scheme);
    if (!authenticated.Succeeded)
    {
        return Challenge(scheme);
    }
 
    var options = _options.Get(scheme);
 
    //var callbackUrl = Url.Page("/Account/SignedOut", pageHandler: null, values: null, protocol: Request.Scheme);
    var callbackUrl = Url.Page("/", pageHandler: null, values: null, protocol: Request.Scheme);
    return SignOut(
        new AuthenticationProperties { RedirectUri = callbackUrl },
        options.AllSchemes);
}
```

## Add Controller to Blazor

The only thing left to do is to make sure your new controller is loaded into the project. Go back into **Startup.cs** and locate the `Configure()` method. Add controller action endpoints by calling the MapControllers() extension for the Endpoints middleware.

```csharp
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});
```

## The Bottom Line

Test your application by attempting to login and logout. For an app running on port 5000, you should be able to activate the SignIn userflow at `http://localhost:5000/Account/SignIn`. When you log out, you should be taken to your applications home page (or whatever location you configured in the controller). To test whether the previous controller was successfully disabled, make sure nothing is available at the old action locations, such as `/AzureADB2C/Account/SignIn`. That’s it! Feel free to make any other customizations to your **AccountController** that you see fit. Let me know in the comments if this tutorial helped you.

[Source](https://wellsb.com/csharp/aspnet/blazor-azure-ad-b2c-custom-url/)