Categories
ASP.NET CORE Azure Blazor

Tutorial: Azure ADB2C with Blazor

This series is specifically for Azure ADB2C with Blazor.

What is Azure ADB2C?

Azure Active Directory B2C provides business-to-customer identity as a service. Your customers use their preferred social, enterprise, or local account identities to get single sign-on access to your applications and APIs.

Infographic of Azure AD B2C identity providers and downstream applications

Azure Active Directory B2C (Azure AD B2C) is a customer identity access management (CIAM) solution capable of supporting millions of users and billions of authentications per day. It takes care of the scaling and safety of the authentication platform, monitoring and automatically handling threats like denial-of-service, password spray, or brute force attacks.

Why Do I need it?

Well, ASP.NET Core has Identity and it works outside the box. With some hacking, you can get it working on mobile apps as well. You can also use IdentityServer4 as your custom identity server that serves additional functionalities as well as offloading resources. But, what if there’s a solution that can address scaling and safety with reasonable good customization and ease of use? That’s what I think Azure AD B2C provides.

Additional benefit: It’s a free service as long the monthly active users is less than 50k.

There’s a lot of documentation on Azure AD B2C. However, they might be outdated and not target specifically for Blazor. Hence, this series aims to help bridge all the gaps.

At high level, the documentations are here:

Microsoft Azure Ad B2C documentation

For WASM:

For Server side, it works right outside the template. The trick is to get access token

That should be it! You should be able to get ID Token and Access Token. You can protect your APIs and validate that Access Token does grant access.

Enjoy the long read… but once you understand how this works, it will save you tons of time in the future develop identity solutions.

Categories
ASP.NET CORE Azure Blazor

Get Access Token from Azure ADB2C for Blazor Server Side

This is part of the series for AAD B2C with Blazor. This post is for Blazor Server Side.

Blazor Server Side is released with default template support for AADB2C. It works great except there’s NO DOCUMENTATION on how to get Access Token.

Luckily, you ran to this post. I’ve gone through it with MSFT engineers and here’s how to hack up a sample. Many thanks to Luke Latham and Javier Calvarro Nelson.

So let’s get down to the code.

First of all, download the sample https://github.com/javiercn/blazor-server-aad-sample

This sample is for AAD and not for AADB2C, so some customizations are needed:

services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme).AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));

Scope need to add:

options.Scope.Add("https://{domain}.onmicrosoft.com/api/demo.read");

//Change response to
changed the options.ResponseType = “code id_token”;

I left out resource since I have no idea what’s that from documentation nor code.

I was able to get the access token.

One side note. His sample code have options.Scope.Add(“offline_access”);

I made the mistake of thinking I only need to add “demo.read” instead of the whole path. Adding the whole path solved my issue. Again, this is not documented? I just happen to read some code that doesn’t work on SO who had this line somewhere.

That’s about it! You can replace Identity with this great service from Azure!

Categories
ASP.NET CORE Azure Blazor

Blazor AAD B2C Additional user flows

This is part of Blazor AAD B2C Series. This post is on Blazor WASM.

Microsoft introduced AADB2C support in Blazor 3.2 Preview: Link

Once followed through my troubleshoot blog, you should be able to get authentication setup. However, what about edit profile and reset password user flow? There’s absolutely NO DOCUMENTATION ON THIS!

Luckily I’ve gone through the process and here’s an example of how to get it to work. Let’s get on with it

  • Registered a callback in the portal for a password reset: https://localhost:5001/passwordreset-callback
  • Have a basic password reset user flow: B2C_1_passwordreset1

In LoginDisplay, Hack up a challenge …

<button class="nav-link btn btn-link" @onclick="ResetPassword">Reset password</button>

...

private void ResetPassword(MouseEventArgs args)
{
    Navigation.NavigateTo("https://XXXXX.b2clogin.com/XXXXX.onmicrosoft.com/oauth2/v2.0/authorize?" +
        "client_id=11111111-1111-1111-1111-111111111111" +
        "&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2Fpasswordreset-callback" +
        "&response_mode=query" +
        "&response_type=id_token" +
        "&scope=openid" +
        $"&nonce={Guid.NewGuid()}" +
        "&state=12345" +
        "&p=B2C_1_passwordreset1");
}

A component to handle the callback (PasswordReset.razor) …

@page "/passwordreset-callback"
@inject NavigationManager Navigation

<p>@_errorMessage</p>
<p>@_errorDescription</p>

@code {
    private string _errorMessage;
    private string _errorDescription;

    protected override void OnInitialized()
    {
        var state = QueryStringHelper.GetParameter(new Uri(Navigation.Uri).Query, "state");

        if (state == "12345")
        {
            var error = QueryStringHelper.GetParameter(new Uri(Navigation.Uri).Query, "error");

            if (error == "")
            {
                Navigation.NavigateTo("/");
            }

            _errorMessage = $"Error: {error}";

            _errorDescription = $"Description: {QueryStringHelper.GetParameter(new Uri(Navigation.Uri).Query, "error_description")}";
        }
    }
}

Use the QueryStringHelper from the repo at https://github.com/dotnet/aspnetcore/blob/blazor-wasm/src/Components/WebAssembly/WebAssembly.Authentication/src/QueryStringHelper.cs.

And… drumroll… it just works.