|
| 1 | +--- |
| 2 | +title: "AuthN-ing Blazor WASM with Azure AD B2C" |
| 3 | +slug: authn-ing-blazor-wasm-with-azure-ad-b2c |
| 4 | +description: "Throughout this post, I'm going to walk through how to integrate Azure AD B2C with Blazor WASM (standalone) app." |
| 5 | +date: "2022-09-23" |
| 6 | +author: Justin-Yoo |
| 7 | +tags: |
| 8 | +- dotnet |
| 9 | +- blazor-wasm |
| 10 | +- azure-ad-b2c |
| 11 | +- authn |
| 12 | +cover: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-00-en.png |
| 13 | +fullscreen: true |
| 14 | +--- |
| 15 | + |
| 16 | +There are many ways to implement authentication and authorisation onto the [Blazor WebAssembly (WASM)][blazor wasm] app. If you publish it to [Azure Static Web Apps (ASWA)][az swa], you can use the built-in authN feature dealt with in my [previous post][post 1]. What if you're publishing your Blazor WASM app onto GitHub Pages? There's no built-in authN feature in this case. However, [Azure AD B2C][az ad b2c] offers a straightforward way for it. You can see literally nothing to write codes to make this happen except a few configurations. Throughout this post, I'm going to discuss how to integrate Azure AD B2C with a standalone type Blazor WASM app. |
| 17 | + |
| 18 | +> You can download a sample application from this [GitHub repository][gh sample]. |
| 19 | +
|
| 20 | + |
| 21 | +## Azure AD vs Azure AD B2C ## |
| 22 | + |
| 23 | +As the naming implies, both [Azure AD][az ad] and [Azure AD B2C][az ad b2c] are similar to each other. In terms of the authentication and authorisation service provider, both are basically the same as each other. |
| 24 | + |
| 25 | +What are some differences, then? Azure AD does granular controls for internal (organisation-wide) resources like SharePoint, Teams, Dynamics365, etc. Azure AD sets permissions on each resource and account. On the other hand, Azure AD B2C provides the same authN-ing feature, but it's for specific applications. As Azure AD B2C works independently from Azure AD, it's NOT for organisation-wide purposes unless it's configured in that way. |
| 26 | + |
| 27 | + |
| 28 | +## Configuring Azure AD B2C ## |
| 29 | + |
| 30 | +Create an Azure AD B2C instance from Azure Portal. You can give any name for it, but let's say `fitabilitydevkr` for now. Then, you'll get the Azure AD B2C instance like below. |
| 31 | + |
| 32 | +![Azure AD B2C][image-01] |
| 33 | + |
| 34 | +Click the "Open B2C Tenant" link to access the Azure AD B2C admin page. On the admin page, click the "App registrations" menu on the left. Then click the "New registration" button at the top. |
| 35 | + |
| 36 | +![Azure AD B2C - New app][image-02] |
| 37 | + |
| 38 | +Enter the details like below: |
| 39 | + |
| 40 | +* Name: Name of the app. Say, `my-fitability-app`. |
| 41 | +* Supported account types: Choose the option "Accounts in any identity provider or organisational directory". |
| 42 | +* Redirect URI (Recommended): Select "Single-page Application (SPA)", then enter `https://localhost/authentication/login-callback`. |
| 43 | +* Permissions: Tick "Grant admin consent to openid and offline_access permissions" |
| 44 | + |
| 45 | +![Azure AD B2C - App registration][image-03] |
| 46 | + |
| 47 | +Once registered, double-check the following details: |
| 48 | + |
| 49 | +* Single-page Application – Redirect URIs |
| 50 | +* Implicit grant and hybrid flows – Access tokens, ID tokens |
| 51 | +* Supported account types – Accounts in any identity provider or organisational directory |
| 52 | + |
| 53 | +![Azure AD B2C - Authentication][image-04] |
| 54 | + |
| 55 | +You can now see the new app registered. Note the application (client) ID. |
| 56 | + |
| 57 | +![Azure AD B2C - Client ID][image-05] |
| 58 | + |
| 59 | +Let's define the log-in process. On the Azure AD B2C page, click the "User flows" menu on the left, then the "New user flow" menu at the top. |
| 60 | + |
| 61 | +![Azure AD B2C - User flow][image-06] |
| 62 | + |
| 63 | +There are many different user flow types. This time, choose the "Sign up and sign in" flow. Then, select "Recommended". |
| 64 | + |
| 65 | +![Azure AD B2C - Sign up and sign in #1][image-07] |
| 66 | + |
| 67 | +Enter the following values, and click "Create". |
| 68 | + |
| 69 | +* Name: `SignUpSignIn` |
| 70 | +* Identity providers: Email Signup |
| 71 | + |
| 72 | +> You can add as many identity providers as you like. But in this post, you can only choose the email sign-up option by default. |
| 73 | +
|
| 74 | +![Azure AD B2C - Sign up and sign in #2][image-08] |
| 75 | + |
| 76 | +Tick more options if you want to include more details in the token. |
| 77 | +만약 토큰에 좀 더 많은 정보를 추가하고 싶다면 아래 내용을 입력하면 좋다. |
| 78 | + |
| 79 | +![Azure AD B2C - Sign up and sign in #3][image-09] |
| 80 | + |
| 81 | +You now complete Azure AD B2C configurations. |
| 82 | + |
| 83 | + |
| 84 | +## Building Blazor WASM App ## |
| 85 | + |
| 86 | +To implement the authN feature with [Azure AD B2C][az ad b2c] on a [Blazor WASM][blazor wasm] app, you first need to create a Blazor WASM project. At the time of this writing, the latest version of [Visual Studio][vs 2022] is `17.3.4`. So, unfortunately, it doesn't create the Blazor WASM project with Azure AD B2C. |
| 87 | + |
| 88 | +![Blazor WASM in VS2022][image-10] |
| 89 | + |
| 90 | +Therefore, you SHOULD use dotnet CLI for it. Enter the command below. You might be noticed the following options: |
| 91 | + |
| 92 | +* `--framework net6.0`: Without giving the framework option explicitly, it uses the latest version of the .NET framework. It explicitly declares the `net6.0` value to fix the framework version. |
| 93 | +* `--hosted false`: If you want to create a standalone Blazor WASM app, use this option. If you want a hosted Blazor WASM app, give this option with `true`. |
| 94 | +* `--auth IndividualB2C`: Choose this option to use Azure AD B2C. |
| 95 | +* `--aad-b2c-instance "https://<TENANT_NAME>.b2clogin.com/"`: It's the login URL of the Azure AD B2C instance. In this post, let's use the tenant name `fitabilitydevkr`. |
| 96 | +* `--domain "<TENANT_NAME>.onmicrosoft.com"`: It's the domain URL of the Azure AD B2C instance. In this post, let's use the tenant name `fitabilitydevkr`. |
| 97 | +* `--client-id`: The client ID value from the app created in the previous section. |
| 98 | +* `--susi-policy-id "B2C_1_SignUpSignIn"`: The policy name for authN. Use the policy name that you just created. In this post, use `SignUpSignIn`. |
| 99 | + |
| 100 | +```powershell |
| 101 | +dotnet new blazorwasm \ |
| 102 | + --output "MyBlazorWasmApp" \ |
| 103 | + --framework net6.0 \ |
| 104 | + --hosted false \ |
| 105 | + --auth IndividualB2C \ |
| 106 | + --aad-b2c-instance "https://<TENANT_NAME>.b2clogin.com/" \ |
| 107 | + --domain "<TENANT_NAME>.onmicrosoft.com" \ |
| 108 | + --client-id "<CLIENT_ID>" \ |
| 109 | + --susi-policy-id "B2C_1_SignUpSignIn" |
| 110 | +``` |
| 111 | + |
| 112 | +Now, you've got Azure AD B2C enabled on the Blazor WASM app. Let's configure the app. Open `Program.cs` and add the `AddMsalAuthentication(...)` method. |
| 113 | + |
| 114 | +```csharp |
| 115 | +builder.Services.AddScoped(sp => new HttpClient |
| 116 | +{ |
| 117 | + BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) |
| 118 | +}); |
| 119 | + |
| 120 | +// ⬇️⬇️⬇️ Add these lines below ⬇️⬇️⬇️ |
| 121 | +builder.Services.AddMsalAuthentication(options => |
| 122 | +{ |
| 123 | + options.ProviderOptions.DefaultAccessTokenScopes.Add("openid"); |
| 124 | + options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access"); |
| 125 | + |
| 126 | + builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication); |
| 127 | +}); |
| 128 | +/// ⬆️⬆️⬆️ Add these lines above ⬆️⬆️⬆️ |
| 129 | +
|
| 130 | +await builder.Build().RunAsync(); |
| 131 | +``` |
| 132 | + |
| 133 | +Then, update `appsettings.json` under the `wwwroot` directory. |
| 134 | + |
| 135 | +```json |
| 136 | +{ |
| 137 | + "AzureAdB2C": { |
| 138 | + "Authority": "https://<TENANT_NAME>.b2clogin.com/<TENANT_NAME>.onmicrosoft.com/B2C_1_SignUpSignIn", |
| 139 | + "ClientId": "<CLIENT_ID>", |
| 140 | + "ValidateAuthority": false |
| 141 | + } |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | +All the configurations on the Blazor WASM app side are done! Build and run the app on your local machine. |
| 146 | + |
| 147 | +![Blazor WASM landing page][image-11] |
| 148 | + |
| 149 | +You will see the "Log in" button at the top right corner. Click it to see the log-in pop-up window. |
| 150 | + |
| 151 | +![Blazor WASM login page][image-12] |
| 152 | + |
| 153 | +Add your email address and password to log-in, or register a new account by clicking the "Sign up now" button. Once you get logged in, you will see the screen like below: |
| 154 | + |
| 155 | +![Blazor WASM logged in][image-13] |
| 156 | + |
| 157 | +Can you see your username? |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +So far, I've walked through how to add the Azure AD B2C authN feature to the standalone type Blazor WASM app. With minimum code change, you can quickly implement the authN feature. In the next post, I'll give a try to add a social media log-in feature to Azure AD B2C. |
| 162 | + |
| 163 | + |
| 164 | +## Want to know more about Blazor? ## |
| 165 | + |
| 166 | +It's great if you visit those sites for more Blazor stuff. |
| 167 | + |
| 168 | +* [Blazor][blazor] |
| 169 | +* [Blazor Tutorials][blazor tutorial] |
| 170 | +* [Blazor Learn][blazor learn] |
| 171 | + |
| 172 | + |
| 173 | +## Want to know more about Azure AD B2C with Blazor? ## |
| 174 | + |
| 175 | +* [Standalone type Blazor WASM with Azure AD B2C][blazor wasm standalone az ad b2c] |
| 176 | +* [Hosted Blazor WASM with Azure AD B2C][blazor wasm hosted az ad b2c] |
| 177 | +* [More security scenarios for Blazor WASM][blazor wasm additional scenarios] |
| 178 | +* [Azure AD B2C user flow policy][az ad b2c userflow] |
| 179 | + |
| 180 | + |
| 181 | +[image-01]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-01-en.png |
| 182 | +[image-02]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-02-en.png |
| 183 | +[image-03]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-03-en.png |
| 184 | +[image-04]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-04-en.png |
| 185 | +[image-05]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-05-en.png |
| 186 | +[image-06]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-06-en.png |
| 187 | +[image-07]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-07-en.png |
| 188 | +[image-08]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-08-en.png |
| 189 | +[image-09]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-09-en.png |
| 190 | +[image-10]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-10-en.png |
| 191 | +[image-11]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-11-en.png |
| 192 | +[image-12]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-12-en.png |
| 193 | +[image-13]: https://sa0blogs.blob.core.windows.net/devkimchi/2022/09/authn-ing-blazor-wasm-with-azure-ad-b2c-13-en.png |
| 194 | + |
| 195 | + |
| 196 | +[post 1]: /2021/09/15/accessing-msgraph-from-blazor-wasm-running-on-aswa/ |
| 197 | + |
| 198 | +[gh sample]: https://github.com/fitability/fitability-app |
| 199 | + |
| 200 | +[vs 2022]: https://visualstudio.microsoft.com/vs/?WT.mc_id=dotnet-77749-juyoo |
| 201 | + |
| 202 | +[blazor]: https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor?WT.mc_id=dotnet-77749-juyoo |
| 203 | +[blazor tutorial]: https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/intro?WT.mc_id=dotnet-77749-juyoo |
| 204 | +[blazor learn]: https://learn.microsoft.com/training/paths/build-web-apps-with-blazor/?WT.mc_id=dotnet-77749-juyoo |
| 205 | +[blazor wasm]: https://learn.microsoft.com/aspnet/core/blazor/?WT.mc_id=dotnet-77749-juyoo#blazor-webassembly |
| 206 | +[blazor wasm standalone az ad b2c]: https://learn.microsoft.com/aspnet/core/blazor/security/webassembly/standalone-with-azure-active-directory-b2c?WT.mc_id=dotnet-77749-juyoo |
| 207 | +[blazor wasm hosted az ad b2c]: https://learn.microsoft.com/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory-b2c?WT.mc_id=dotnet-77749-juyoo |
| 208 | +[blazor wasm additional scenarios]: https://learn.microsoft.com/aspnet/core/blazor/security/webassembly/additional-scenarios?WT.mc_id=dotnet-77749-juyoo |
| 209 | + |
| 210 | +[az swa]: https://learn.microsoft.com/azure/static-web-apps/overview?WT.mc_id=dotnet-77749-juyoo |
| 211 | +[az ad]: https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-whatis?WT.mc_id=dotnet-77749-juyoo |
| 212 | +[az ad b2c]: https://learn.microsoft.com/azure/active-directory-b2c/overview?WT.mc_id=dotnet-77749-juyoo |
| 213 | +[az ad b2c userflow]: https://learn.microsoft.com/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-user-flow&WT.mc_id=dotnet-77749-juyoo |
0 commit comments