Blazor.BFF.AzureAD.Template 1.2.2

There is a newer version of this package available.
See the version list below for details.
dotnet new install Blazor.BFF.AzureAD.Template::1.2.2
This package contains a .NET Template Package you can call from the shell/command line.

Blazor.BFF.AzureAD.Template

.NET NuGet Status Change log

This template can be used to create a Blazor WASM application hosted in an ASP.NET Core Web app using Azure AD and Microsoft.Identity.Web to authenticate using the BFF security architecture. (server authentication) This removes the tokens form the browser and uses cookies with each HTTP request, response. The template also adds the required security headers as best it can for a Blazor application.

Features

  • WASM hosted in ASP.NET Core 6
  • BFF with Azure AD using Microsoft.Identity.Web
  • OAuth2 and OpenID Connect OIDC
  • No tokens in the browser
  • Azure AD Continuous Access Evaluation CAE support

Using the template

install

dotnet new -i Blazor.BFF.AzureAD.Template

run

dotnet new blazorbffaad -n YourCompany.Bff

Use the -n or --name parameter to change the name of the output created. This string is also used to substitute the namespace name in the .cs file for the project.

Setup after installation

Add the Azure AD App registration settings

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[Enter the domain of your tenant, e.g. contoso.onmicrosoft.com]",
    "TenantId": "[Enter 'common', or 'organizations' or the Tenant Id (Obtained from the Azure portal. Select 'Endpoints' from the 'App registrations' blade and use the GUID in any of the URLs), e.g. da41245a5-11b3-996c-00a8-4d99re19f292]",
    "ClientId": "[Enter the Client Id (Application ID obtained from the Azure portal), e.g. ba74781c2-53c2-442a-97c2-3d60re42f403]",
    "ClientSecret": "[Copy the client secret added to the app from the Azure portal]",
    "ClientCertificates": [
    ],
    // the following is required to handle Continuous Access Evaluation challenges
    "ClientCapabilities": [ "cp1" ],
    "CallbackPath": "/signin-oidc"
  },

Add the scopes for the downstream API if required

  "DownstreamApi": {
    "Scopes": "User.ReadBasic.All user.read"
  },

Use Continuous Access Evaluation CAE with a downstream API (access_token)

Azure app registration manifest
"optionalClaims": {
	"idToken": [],
	"accessToken": [
		{
			"name": "xms_cc",
			"source": null,
			"essential": false,
			"additionalProperties": []
		}
	],
	"saml2Token": []
},

Any API call for the Blazor WASM could be implemented like this:

[HttpGet]
public async Task<IActionResult> Get()
{
  try
  {
	// Do logic which calls an API and throws claims challenge 
	// WebApiMsalUiRequiredException. The WWW-Authenticate header is set
	// using the OpenID Connect standards and Signals spec.
  }
  catch (WebApiMsalUiRequiredException hex)
  {
	var claimChallenge = WwwAuthenticateParameters
		.GetClaimChallengeFromResponseHeaders(hex.Headers);
		
	return Unauthorized(claimChallenge);
  }
}

The downstream API call could be implemented something like this:

public async Task<T> CallApiAsync(string url)
{
	var client = _clientFactory.CreateClient();

	// ... add bearer token
	
	var response = await client.GetAsync(url);
	if (response.IsSuccessStatusCode)
	{
		var stream = await response.Content.ReadAsStreamAsync();
		var payload = await JsonSerializer.DeserializeAsync<T>(stream);

		return payload;
	}

	// You can check the WWW-Authenticate header first, if it is a CAE challenge
	
	throw new WebApiMsalUiRequiredException($"Error: {response.StatusCode}.", response);
}

Use Continuous Access Evaluation CAE in a standalone app (id_token)

Azure app registration manifest
"optionalClaims": {
	"idToken": [
		{
			"name": "xms_cc",
			"source": null,
			"essential": false,
			"additionalProperties": []
		}
	],
	"accessToken": [],
	"saml2Token": []
},

If using a CAE Authcontext in a standalone project, you only need to challenge against the claims in the application.

private readonly CaeClaimsChallengeService _caeClaimsChallengeService;

public AdminApiCallsController(CaeClaimsChallengeService caeClaimsChallengeService)
{
  _caeClaimsChallengeService = caeClaimsChallengeService;
}

[HttpGet]
public IActionResult Get()
{
  // if CAE claim missing in id token, the required claims challenge is returned
  var claimsChallenge = _caeClaimsChallengeService
	.CheckForRequiredAuthContextIdToken(AuthContextId.C1, HttpContext);

  if (claimsChallenge != null)
  {
	return Unauthorized(claimsChallenge);
  }

uninstall

dotnet new -u Blazor.BFF.AzureAD.Template

Credits, Used NuGet packages + ASP.NET Core 6.0 standard packages

  • NetEscapades.AspNetCore.SecurityHeaders

https://github.com/AzureAD/microsoft-identity-web

https://damienbod.com/2022/04/20/implement-azure-ad-continuous-access-evaluation-in-an-asp-net-core-razor-page-app-using-a-web-api/

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.1.1 1,413 2/1/2024
3.1.0 1,328 1/14/2024
3.0.2 1,092 12/31/2023
3.0.1 1,659 12/7/2023
2.2.0 2,127 11/3/2023
2.1.0 7,939 6/22/2023
2.0.2 1,463 3/11/2023
2.0.1 1,167 1/22/2023
2.0.0 1,813 12/3/2022
1.2.7 3,394 9/23/2022
1.2.6 6,240 8/12/2022
1.2.5 1,762 8/7/2022
1.2.4 3,966 7/9/2022
1.2.3 6,721 5/22/2022
1.2.2 439 5/22/2022
1.2.1 1,751 5/20/2022
1.2.0 469 5/20/2022
1.1.0 5,459 3/20/2022
1.0.10 4,097 3/5/2022
1.0.9 6,278 2/11/2022
1.0.8 3,298 1/23/2022
1.0.7 1,091 1/21/2022
1.0.6 539 1/17/2022
1.0.5 2,054 1/9/2022
1.0.4 1,472 1/4/2022
1.0.2 7,551 12/9/2021
1.0.0 603 11/30/2021

use new top-level statements and remove, enable ImplicitUsings, add IAntiforgeryHttpClientFactory/AntiforgeryHttpClientFactory, Replace of IdentityModel with System.Security.Claims and remove IdentityModel nuget package