在 ASP.NET Core 中使用 Azure Active Directory B2C 进行云身份验证

作者:Damien Bod

Azure Active Directory B2C (Azure AD B2C) 是一种适用于 Web 应用和移动应用的云标识管理解决方案。 该服务为托管在云和本地的应用提供身份验证。 身份验证类型包括个人帐户、社交网络帐户和联合企业帐户。 此外,Azure AD B2C 可以通过最少的配置提供多重身份验证。

提示

Microsoft Entra ID、Microsoft Entra External ID 和 Azure AD B2C 是单独的产品/服务。 Entra ID 租户通常代表组织,而 Azure AD B2C 租户或 Microsoft Entra External ID 租户代表要用于信赖方应用的标识集合。 若要了解详细信息,请参阅 Azure AD B2C:常见问题解答 (FAQ)

提示

面向客户的 Microsoft Entra 外部 ID 是 Microsoft 新的客户 identity 和访问管理 (CIAM) 解决方案。

本教程介绍如何配置 ASP.NET Core 应用,以使用 Azure AD B2C 进行身份验证。

先决条件

准备工作

  1. 创建 Azure Active Directory B2C 租户

  2. 创建新的 ASP.NET Core Razor Pages 应用:

    dotnet new razor -o azure-ad-b2c
    

    上一个命令将在名为 azure-ad-b2c 的目录中创建 Razor Pages 应用。

    提示

    你可能想要使用 Visual Studio 来创建应用

  3. 在租户中创建 Web 应用注册。 对于重定向 URI,请使用 https://localhost:5001/signin-oidc。 使用 Visual Studio 生成的端口时,将 5001 替换为应用使用的端口。

修改应用

  1. Microsoft.Identity.WebMicrosoft.Identity.Web.UI 包添加到项目中。 如果使用 Visual Studio,则可以使用 NuGet 包管理器

    dotnet add package Microsoft.Identity.Web
    dotnet add package Microsoft.Identity.Web.UI
    

    在上述代码中:

    • Microsoft.Identity.Web 包括用于通过 Microsoft identity 平台进行身份验证的基本依赖项集。
    • Microsoft.Identity.Web.UI 包括封装在名为 MicrosoftIdentity 的区域中的 UI 功能。
  2. AzureADB2C 对象添加到 appsettings.json

    注意

    使用 Azure B2C 用户流时,需要设置流类型的 Instance 和 PolicyId。

    {
      "AzureADB2C": {
        "Instance": "https://--your-domain--.b2clogin.com",
        "Domain": "[Enter the domain of your B2C 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]",
        // Use either a secret or a certificate. ClientCertificates are recommended.
        "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 your policy here
        "SignUpSignInPolicyId": "B2C_1_signup_signin",
        "SignedOutCallbackPath": "/signout-callback-oidc"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*"
    }
    
    • 对于 Domain,请使用 Azure AD B2C 租户的域。
    • 对于 ClientId,请使用在租户中创建的应用注册中的“应用程序(客户端) ID”。
    • 对于 Instance,请使用 Azure AD B2C 租户的域。
    • 对于 SignUpSignInPolicyId,请使用 Azure B2C 租户中定义的用户流策略
    • 使用 ClientSecret 或 ClientCertificate 配置。 建议使用 ClientCertificate。
    • 其他所有值均保持不变。
  3. 在 Pages/Shared 中,创建名为 _LoginPartial.cshtml 的文件。 包括以下代码:

    @using System.Security.Principal
    
    <ul class="navbar-nav">
    @if (User.Identity?.IsAuthenticated == true)
    {
            <span class="navbar-text text-dark">Hello @User.Identity?.Name!</span>
            <li class="nav-item">
                <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut">Sign out</a>
            </li>
    }
    else
    {
            <li class="nav-item">
                <a class="nav-link text-dark" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
            </li>
    }
    </ul>
    

    前面的代码:

    • 检查用户是否已通过身份验证。
    • 根据情况呈现“注销”或“登录”链接。
      • 该链接指向 MicrosoftIdentity 区域中 Account 控制器上的操作方法。
  4. 在 Pages/Shared/_Layout.cshtml 中,在 <header> 元素内添加突出显示的行:

    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">azure_ad_b2c</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>
            </div>
        </nav>
    </header>
    

    如果添加 <partial name="_LoginPartial" />,会在使用此布局的每个页面请求中呈现 _LoginPartial.cshtml 分部视图。

  5. 在 Program.cs 中,进行以下更改:

    1. 然后,添加以下 using 指令:

      using Microsoft.Identity.Web;
      using Microsoft.Identity.Web.UI;
      using Microsoft.AspNetCore.Authentication.OpenIdConnect;
      

      上述代码解析了后续步骤中使用的引用。

    2. 使用以下代码更新 builder.Services 行:

      builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
              .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureADB2C"));
      
      builder.Services.AddAuthorization(options =>
      {
          // By default, all incoming requests will be authorized according to 
          // the default policy
          options.FallbackPolicy = options.DefaultPolicy;
      });
      builder.Services.AddRazorPages(options => {
          options.Conventions.AllowAnonymousToPage("/Index");
      })
      .AddMvcOptions(options => { })
      .AddMicrosoftIdentityUI();
      

      在上述代码中:

      • 调用 AddAuthenticationAddMicrosoftIdentityWebApp 方法会将应用配置为使用专为 Microsoft identity 平台配置的 Open ID Connect。
      • AddAuthorization 初始化 ASP.NET Core 授权。
      • AddRazorPages 调用配置应用,以便匿名浏览器可以查看索引页面。 所有其他请求都需要进行身份验证。
      • AddMvcOptionsAddMicrosoftIdentityUI 添加重定向至/自 Azure AD B2C 所需的 UI 组件。
    3. 将突出显示的行更新到 Configure 方法中:

      app.UseRouting();
      
      app.UseAuthentication();
      app.UseAuthorization();
      
      app.MapRazorPages();
      

      上述代码将在 ASP.NET Core 中启用身份验证。

运行应用

注意

使用与 Azure 应用注册重定向 URI 匹配的配置文件

  1. 运行应用。

    dotnet run --launch-profile https
    
  2. 浏览到应用的安全终结点,例如 https://localhost:5001/

    • 索引页面呈现时没有身份验证质询。
    • 标头包含“登录”链接,因为你未进行身份验证。
  3. 选择 Privacy 链接。

    • 浏览器重定向到租户配置的身份验证方法。
    • 登录后,标头显示欢迎消息和“注销”链接。

后续步骤

本教程介绍了如何配置 ASP.NET Core 应用,以使用 Azure AD B2C 进行身份验证。

现在,ASP.NET Core 应用已配置为使用 Azure AD B2C 进行身份验证,你可以使用 Authorize 属性来保护应用。 通过学习以下内容,继续开发应用: