Blazor Test App for Azure AD B2C Custom Policies
Azure AD B2C can be both fun and frustrating. You can customize a lot (which we love). But it's not always easy doing so (which we sometimes look upon less favorably). This post is not about how best to work the xml mojo with custom policies. What we will try to make smoother is the testability part.
Let me take a step back here and explain. The built-in policies are great as a user-friendly way for implementing simple authentication use cases. A couple of clicks in the Azure Portal to create a policy, test it in the Portal as well, and send off a couple of parameters to the dev team to inject in their code and that's it. In theory.
Unfortunately it doesn't always work out that way in practice. You need that extra little thing the user flows can't do so you need custom policies. You need icons on your page for supporting different languages. You need to test different policies for different use cases. You need extra parameters. So you end up manually building different urls, or you have a test app where you change the code and restart.
Things are ever evolving in the .NET world though, so you can actually do things a little more dynamically now than the early days of AAD B2C.
Microsoft has detailed how you can add overrides to the authentication pipeline to achieve most of this in .NET-based apps:
The article is snippet-based and I didn't spot a complete sample app though, so I assembled a Blazor app intended to work as a testbed. And the test-part is important - there's no sanitation of inputs so you cannot plug this code directly into actual apps, but the concept should be transferable if you need it. Just tweak as you seem fit.
The code can be found here:
https://github.com/ahelland/Identity-CodeSamples-v2/tree/master/aad-b2c-custom_policies-dotnet6
It has a very sexy UI:
The structure is simple enough:
Some Razor markup:
A little code behind the scenes:
And overriding the authentication middleware
You set up the different parameters you need and hit the Generate url button (which might have been more precise to call uri) and then hit the Log in button to actually do the login. (The template in Visual Studio enables autotriggering login on startup, and since that is not what we want here that has been disabled.) The url is not the actual redirect to Azure, but the instructions for the middleware to generate the actual url and send you there. This is an important part - it is of course possible to construct urls manually based on the info you supply, but as a security measure your .NET web app will not accept responses that did not originate from the app so you will hit an error of some sort if you don't loop things through the auth middleware.
Before hitting the F5 button to start the app remember to step into appsettings.json and fill in the corresponding values there to interact with B2C.
The supported options are described both in the docs article and inline in the code so I'm not going to explain all of them. Well, apart from the "p" query parameter which allows you to build a url that points to one policy in the base part of the url while actually running a different policy. Yeah, real clean looking, I know :)
Meaning that you can get a url that looks like this:
https://contoso.b2clogin.com/contoso.onmicrosoft.com/b2c_1A_SignUp/oauth2/v2.0/authorize?client_id=...&p=B2C_1A_SignIn where "SignIn" is the one actually being run. (The base policy defined in appsettings.json will need to be valid to bootstrap the app.)
The ID token is a powerful trick that can be used both for SignUp and SignIn. Basically you have info about the user beforehand that you can use to supply more context to Azure AD B2C. I have an old article on how to use that for "magic links" and pre-seeded SignUp, but intend to publish a more up to date version of that soon.
There's plenty more to build out a proper app with Azure AD B2C - in addition to the actual policies of course. Hopefully this will help you along the way.
Published on:
Learn moreRelated posts
Azure Developer CLI (azd): Run and test AI agents locally with azd
New azd ai agent run and invoke commands let you start and test AI agents from your terminal—locally or in the cloud. The post Azure Developer...
Microsoft Purview compliance portal: Endpoint DLP classification support for Azure RMS–protected Office documents
Microsoft Purview Endpoint DLP will soon classify Azure RMS–protected Office documents, enabling consistent DLP policy enforcement on encrypte...
Introducing the Azure Cosmos DB Plugin for Cursor
We’re excited to announce the Cursor plugin for Azure Cosmos DB bringing AI-powered database expertise, best practices guidance, and liv...
Azure DevOps Remote MCP Server (public preview)
When we released the local Azure DevOps MCP Server, it gave customers a way to connect Azure DevOps data with tools like Visual Studio and Vis...
Azure Cosmos DB at FOSSASIA Summit 2026: Sessions, Conversations, and Community
The FOSSASIA Summit 2026 was an incredible gathering of developers, open-source contributors, startups, and technology enthusiasts from across...
Azure Cosmos DB at FOSSASIA Summit 2026: Sessions, Conversations, and Community
The FOSSASIA Summit 2026 was an incredible gathering of developers, open-source contributors, startups, and technology enthusiasts from across...
Dataverse: Avoid Concurrency issues by using Azure Service Bus Queue and Azure Functions
Another blog post to handle the concurrency issue. Previously, I shared how to do concurrency via a plugin in this blog post and also how to f...
March Patches for Azure DevOps Server
We are releasing patches for our self‑hosted product, Azure DevOps Server. We strongly recommend that all customers stay on the latest, most s...