Blazor Test App for Azure AD B2C Custom Policies
Published Jul 05 2022 09:00 AM 5,159 Views
Iron Contributor

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:

https://docs.microsoft.com/en-us/azure/active-directory-b2c/enable-authentication-web-application-op...

 

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:

Index.png

 

 

 

 

The structure is simple enough:

Some Razor markup:

<div class="form-group row">
  <label for="loginHint" class="col-sm-4 col-form-label">loginHint</label>
  <InputText id="loginHint" @bind-Value="@parameters.loginHint" class="form-control col-sm-4" placeholder="bob@contoso.com"></InputText>
  <ValidationMessage class="offset-sm-3 col-sm-8" For="@(() => parameters.loginHint)" />
</div>

 

A little code behind the scenes:

   

if (!string.IsNullOrEmpty(parameters.loginHint))
{               
  queryParams.Add("loginHint", parameters.loginHint);
}

And overriding the authentication middleware

async Task OnRedirectToIdentityProviderFunc(RedirectContext arg)
{
  //Prepopulate the sign-in name
  string loginHint = arg.HttpContext.Request.Query["loginHint"];
  if (loginHint != null)
  { 
    arg.ProtocolMessage.LoginHint = loginHint; 
  }
  
  await Task.CompletedTask.ConfigureAwait(false);
}

 

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=.... 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.

Co-Authors
Version history
Last update:
‎Jul 05 2022 09:00 AM
Updated by: