我可以将 MFA 应用于 Azure ADB2C 中的每个用户吗?

Can I apply MFA to each user in Azure ADB2C?

我使用了自定义策略来创建登录屏幕。 我们希望 运行 基于每个用户的 MFA。 例如,我有两个用户帐户。(user1, user2) 用户 1 想在不使用 MFA 的情况下登录。 用户 2 申请 MFA 并想要登录。 然后,两个用户都访问相同的 URL 进行登录。 哪里可以这样给每个用户设置一个MFA?

使用 build-in 用户流程,这是不可能的。您需要使用自定义策略并允许基于某些自定义的 MFA 属性(例如角色管理员/普通用户)。

这里有一个 link 可以帮助您获得一些与实施自定义 MFA 相关的指导:

https://www.kallemarjokorpi.fi/blog/azure-b2c-custom-mfa-implementation.html

我已经能够通过自定义政策(一项政策用于注册,第二项政策用于取消注册)实施 self-service 每个用户 TOTP MFA enrollment/unenrollment。

我的想法是最终用户决定是否要使用 TOTP MFA。

到目前为止,这只是一个 PoC 实现,但在我的测试中它运行良好。

它基于 GitHub - https://github.com/azure-ad-b2c/samples/tree/master/policies/totp.

上可用的 TOTP MFA 样本

我的 UserJourneys 的相关部分:

  1. 启用 MFA UserJourney
<UserJourney Id="EnableMFA" DefaultCpimIssuerTechnicalProfileReferenceId="JwtIssuer">
  <OrchestrationSteps>
    //Default steps for signing in user with Local/Social account
    [...]

    <OrchestrationStep Order="5" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CheckAvailableDevices" TechnicalProfileReferenceId="AzureMfa-GetAvailableDevices" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="6" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>numberOfAvailableDevices</Value>
          <Value>0</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="CreateErrorResponse-MfaAlreadyEnabled" TechnicalProfileReferenceId="CreateErrorResponse-MfaAlreadyEnabled" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="ReturnOAuth2Error">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
          <Value>numberOfAvailableDevices</Value>
          <Value>0</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
    </OrchestrationStep>

    <OrchestrationStep Order="8" Type="InvokeSubJourney">
      <JourneyList>
        <Candidate SubJourneyReferenceId="TotpFactor-Input" />
      </JourneyList>
    </OrchestrationStep>

    <OrchestrationStep Order="9" Type="InvokeSubJourney">
      <JourneyList>
        <Candidate SubJourneyReferenceId="TotpFactor-Verify" />
      </JourneyList>
    </OrchestrationStep>

    <OrchestrationStep Order="10" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />

</UserJourney>

第 5 步读取 numberOfAvailableDevices,表示用户是否已注册 (numberOfAvailableDevices=1) 或未注册 (numberOfAvailableDevices=0)。

如果用户已经注册,第 6 步和第 7 步将创建并return发送错误通知用户他不能启用 MFA,因为它已经启用。

第 8 步和第 9 步正在注册用户。这些步骤取自 GitHub 示例。

  1. 禁用 MFA UserJourney

此处,AzureMfaProtocolProvider 技术提供商不支持取消注册 TOTP MFA。可在此处找到可用操作列表 - https://docs.microsoft.com/en-us/azure/active-directory-b2c/multi-factor-auth-technical-profile#totp-mode.

要取消注册用户,您可以使用 Microsoft Graph(需要为您的 API 自定义 REST 技术配置文件)。

https://docs.microsoft.com/en-us/graph/api/resources/softwareoathauthenticationmethod?view=graph-rest-beta

使用这些端点,您可以为特定用户列出 softwareOathMethods 并在需要时将其删除。如果用户启用了 TOTP MFA,则 MS Graph 应该 return 一个包含 1 softwareOathMethod.

的数组

用户旅程:

<UserJourney Id="DisableMFA" DefaultCpimIssuerTechnicalProfileReferenceId="JwtIssuer">
  <OrchestrationSteps>
    //Default steps for signing in user with Local/Social account
    [...]

    <OrchestrationStep Order="5" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="CheckAvailableDevices" TechnicalProfileReferenceId="AzureMfa-GetAvailableDevices" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="6" Type="ClaimsExchange">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>numberOfAvailableDevices</Value>
          <Value>0</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
      <ClaimsExchanges>
        <ClaimsExchange Id="CreateErrorResponse-MfaNotEnabled" TechnicalProfileReferenceId="CreateErrorResponse-MfaNotEnabled" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="ReturnOAuth2Error">
      <Preconditions>
        <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
          <Value>numberOfAvailableDevices</Value>
          <Value>0</Value>
          <Action>SkipThisOrchestrationStep</Action>
        </Precondition>
      </Preconditions>
    </OrchestrationStep>

    <OrchestrationStep Order="8" Type="InvokeSubJourney">
      <JourneyList>
        <Candidate SubJourneyReferenceId="TotpFactor-Verify" />
      </JourneyList>
    </OrchestrationStep>

    <OrchestrationStep Order="9" Type="ClaimsExchange">
      <ClaimsExchanges>
        <ClaimsExchange Id="REST-DisableMfa" TechnicalProfileReferenceId="REST-DisableMfa" />
      </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="10" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
  </OrchestrationSteps>
  <ClientDefinition ReferenceId="DefaultWeb" />

</UserJourney>

步骤 5、6 和 7 类似于前面提到的 EnableMFA UserJourney 中的相应步骤。

第 8 步强制用户在禁用 MFA 之前从他的身份验证器应用程序输入 TOTP 代码,因此我们确定他是帐户的所有者。

在第 9 步中,REST-DisableMfa 技术配置文件是我的自定义 REST api,然后调用 Microsoft Graph api。