Categories
ASP.NET CORE Azure Blazor

Blazor WASM Call WebAPI Without Access Token

This is for Blazor WASM RC.

So imagine you have a Blazor WASM app, which is a SPA that user might need to sign in to perform some tasks via Web API. Take the case using Azure AD B2C, once we logged in, we’ll have ID and Access Token from Implicit Flow.

By default, the AADB2C template generates the following:

        builder.Services.AddHttpClient("HostedB2C.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
            .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
        // Supply HttpClient instances that include access tokens when making requests to the server project
        builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("HostedB2C.ServerAPI"));

This makes all WebAPIs with Access Token, refresh and such, which is great, secure and convenient.

However, what if there’s a need to call WebAPI as anonymous user?

As of now, there’s no official documentation (should be coming soon). Basically, we can add multiple AddHttpClient for the use case without auth.

To see this in action. In Program.cs, add

        builder.Services.AddHttpClient("HostedB2C.ServerAPI.NoAuth",
                client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));

In the razor component:

@inject IHttpClientFactory ClientFactory

        var client = ClientFactory.CreateClient("HostedB2C.ServerAPI.NoAuth");
        forecasts = await client.GetFromJsonAsync<WeatherForecast[]>("WeatherForecastNA");

There! Now we can call WebAPI using alternative HttpClient (the one without auth).

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.

Categories
ASP.NET CORE Azure Blazor

TROUBLESHOOT: ASP.NET Core Blazor WebAssembly hosted app with Azure Active Directory B2C

In Blazor WASM 3.2.0 Preview 2, Microsoft announced support for Token-based authentication. In particular, IdentityServer, OpenID Connect provider, and Azure Active Directory B2C.

THIS ARTICLE IS SPECIFICALLY FOR AZURE ACTIVE DIRECTORY B2C

Follow the guide: https://docs.microsoft.com/en-us/aspnet/core/security/blazor/webassembly/hosted-with-azure-active-directory-b2c?view=aspnetcore-3.1#create-the-app

We should be able to create an app that’s able to use AAD B2C for login and use API securely.

In creating the app, it requires carefully crafted command to create the app: dotnet new blazorwasm -au IndividualB2C –aad-b2c-instance “{AAD B2C INSTANCE}” –api-client-id “{SERVER API APP CLIENT ID}” –app-id-uri “{APP ID URI}” –client-id “{CLIENT APP CLIENT ID}” –default-scope “{DEFAULT SCOPE}” –domain “{DOMAIN}” -ho -ssp “{SIGN UP OR SIGN IN POLICY}” –tenant-id “{TENANT ID}”

I tried this several times and I keeps on getting weird issues.

  1. On Chrome, I’ll get some weird PERMISSION issue. It works on Firefox and Edge, so this is probably not something I did wrong. Most likely will get fixed in the future.
  2. After Login, LoginDisplay gets my displayname correctly, however, when visit FetchData, the app will crash due to token been null

For 2, after hours, seems create app generation might cause an issue in builder.Services.AddMsalAuthentication.

Incorrect Generated: options.ProviderOptions.DefaultAccessTokenScopes.Add(“https:// XXXXXX.onmicrosoft.com/https:// XXXXXX.onmicrosoft.com/11111111-1111-1111-1111-111111111111/API.Access”);

Working solution:

options.ProviderOptions.DefaultAccessTokenScopes.Add(“https://XXXXXX.onmicrosoft.com/11111111-1111-1111-1111-111111111111/API.Access”);

Hopefully this helps someone else.

Categories
ASP.NET CORE Blazor Products

Experimental Blazor Mobile (binding) on iOS

About a month ago, Jan 14, 2020, Microsoft announced an experimental Mobile Blazor Binding.

The reference link is here

I tried and it ran well on Android. However, we got a nasty crash on startup for iOS. In particular, the dreadful

System.PlatformNotSupportedException: Operation is not supported on this platform.

After few weeks, the solutions are finally out and we can start experimenting with it.

In particular, to fix the iOS crash, there are two parts:

  1. Use different Generic Host options: #51
  2. Fix MainPage initialization: #76

I can confirm this works. Eilon also mentioned they plan to have monthly releases and hopefully a nuget feed.

Happy Hacking!

Categories
ASP.NET CORE Azure Blazor Products Razor Pages

2020 Web Dev Learning Essentials

Below demonstrates the necessary knowledge required to become a reasonable Web Developer at 2020. This is tailored for .NET Developer.

Will update this into flow charts in the near future.

Categories
ASP.NET CORE Blazor Razor Pages

Project Setup Flow Chart

This is my typical Project Setup Flow Chart

Categories
ASP.NET CORE Blazor Razor Pages

Learning Next Steps

This is a follow up to Quick-Start, Part IV of the Series Web Development for Experienced (Non-Web) Software Engineers

Microsoft’s documentation is one of the main learning resource. Mainly due to it’s closeness to the actual source and fairly up-to-date. You can find the link here.

While ASP.NET Core’s available for several years, it continuously to evolves at an astonishing rate. Anyone who follows the preview builds might be able to understand some of the design decisions. Without them, often times it won’t make much sense. This is where I find Microsoft documentation lacking. I’ll try to provide more value discussion the changes and hidden features in this site.

Categories
ASP.NET CORE Blazor Razor Pages

Web App Differences

In Quick-start post of Web Development for Experienced (Non-Web) Engineers series, I mentioned different type of web apps. This post I’ll try to clarify what they mean.

Name App Type Description
Razor PagesWeb AppRazor Pages is closer to Model-View-Viewmodel pattern. Razor Pages is a server-side, page-centric programming model, encourages organization of files by feature, therefore easing maintenance of your application. It contains same syntax and functionalities of MVC, but enables two-way data binding and simpler development experience with isolated concerns.
MVCWeb App Model-View-Controller pattern. The Model defines the fundamental behaviors and data for the application and its components. The View uses HTML and Razor syntax to provide the UI. The Controller is a class that receives requests and handles user actions. At the time of writing .Net Core 3.1. MVC is considered as legacy.
Web APIWeb APIJust APIs
SignalRReal-Time AppWeb technologies was initially designed as pull/get protocol, where the request for the transmission of information is initiated by the receiver or client. To achieve two way communication, several techniques were used previously, such as long-poll, server-side event. With the introduction of Web Socket, two way communication is standardized (but still hard to use). SignalR is a wrapper to make development of real-time app much easier to develop.
BlazorBlazor/SPA AppThe future. Single Page Apps web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server. This approach avoids interruption of the user experience between successive pages, making the application behave more like a desktop application. Several popular SPA frameworks: Angular, React, Vue. Blazor is Microsoft’s approach of making SPA, enabling C# development across web client, server, mobile.