次の方法で共有


Azure Active Directory B2C でリソース所有者のパスワード資格情報フローを設定する

重要

2025 年 5 月 1 日より、Azure AD B2C は新規のお客様向けに購入できなくなります。 詳細については、FAQ を参照してください

開始する前にこのページの上部にある ポリシーの種類 セレクターを使用して、設定するポリシーの種類を選択します。 Azure Active Directory B2C には、ユーザーがアプリケーションを操作する方法を定義する 2 つの方法 (定義済みのユーザー フローを使用する、または完全に構成可能なカスタム ポリシーを使用する) があります。 この記事で必要な手順は、方法ごとに異なります。

Azure Active Directory B2C (Azure AD B2C) では、リソース所有者パスワード資格情報 (ROPC) フローは OAuth 標準認証フローです。 このフローでは、証明書利用者とも呼ばれるアプリケーションが、トークンの有効な資格情報を交換します。 資格情報には、ユーザー ID とパスワードが含まれます。 返されるトークンは、ID トークン、アクセス トークン、および更新トークンです。

警告

ROPC フロー は使用しないことを お勧めします。 ほとんどのシナリオでは、より安全な代替手段が利用でき、推奨されます。 このフローでは、アプリケーションに非常に高い信頼が必要であり、他のフローに存在しないリスクが伴います。 このフローは、より安全なフローが実行可能ではない場合にのみ使用してください。

ROPC フロー ノート

Azure Active Directory B2C (Azure AD B2C) では、次のオプションがサポートされています。

  • ネイティブ クライアント: 認証時のユーザー操作は、ユーザー側デバイスでコードが実行されるときに発生します。 デバイスは、Android や iOS などのネイティブ オペレーティング システムで実行されているモバイル アプリケーションにすることができます。
  • パブリック クライアント フロー: アプリケーションによって収集されたユーザー資格情報のみが API 呼び出しで送信されます。 アプリケーションの資格情報は送信されません。
  • 新しい要求の追加: ID トークンの内容を変更して、新しい要求を追加できます。

次のフローはサポートされていません。

  • サーバー間: ID 保護システムには、対話の一環として呼び出し元 (ネイティブ クライアント) から収集された信頼性の高い IP アドレスが必要です。 サーバー側 API 呼び出しでは、サーバーの IP アドレスのみが使用されます。 失敗した認証の動的しきい値を超えた場合、ID 保護システムは繰り返し IP アドレスを攻撃者として識別する可能性があります。
  • 機密クライアント フロー: アプリケーション クライアント ID は検証されますが、アプリケーション シークレットは検証されません。

ROPC フローを使用する場合は、次の制限事項を考慮してください。

  • ROPC は、ユーザーの操作を必要とする認証フローが中断された場合には機能しません。 たとえば、パスワードの有効期限が切れた場合や変更する必要がある場合、 多要素認証 が必要な場合や、サインイン時に詳細情報を収集する必要がある場合 (ユーザーの同意など)。
  • ROPC では、ローカル アカウントのみがサポートされます。 ユーザーは、Microsoft、Google+、X、AD-FS、Facebook などの フェデレーション ID プロバイダー でサインインできません。
  • サインインしたままにする (KMSI) などのセッション管理は適用されません。

アプリケーションを登録する

Azure AD B2C テナントにアプリケーションを登録するには、新しい統合 アプリ登録 エクスペリエンスまたはレガシ アプリケーション (レガシ) エクスペリエンスを使用できます。 新しいエクスペリエンスの詳細を確認します。

  1. Azure portal にサインインします。
  2. Azure AD B2C テナントを含むディレクトリを使用していることを確認します。
    1. ポータル ツールバーの [Directories + subscriptions](ディレクトリ + サブスクリプション) アイコンを選択します。
    2. [ポータルの設定] | [Directories + subscriptions](ディレクトリ + サブスクリプション) ページの [ディレクトリ名] の一覧で自分の Azure AD B2C ディレクトリを見つけて、 [切り替え] を選択します。
  3. Azure portal で、Azure AD B2C を検索して選択します
  4. [アプリの登録] を選択し、[新しい登録] を選択します。
  5. アプリケーションの名前を入力します。 たとえば、 ROPC_Auth_app
  6. 他の値はそのままにして、[ 登録] を選択します。
  7. 後の手順で使用する アプリケーション (クライアント) ID を 記録します。
  8. [管理] で、 [認証] を選択します。
  9. [ 新しいエクスペリエンスを試す ] を選択します (表示されている場合)。
  10. [ 詳細設定] と [ 次のモバイルおよびデスクトップ フローを有効にする] セクションで、[ はい ] を選択して、アプリケーションをパブリック クライアントとして扱います。 この設定は、ROPC フローに必要です。
  11. 保存 を選択します。
  12. 左側のメニューで、[ マニフェスト ] を選択してマニフェスト エディターを開きます。
  13. oauth2AllowImplicitFlow 属性を true に設定します。 属性が存在しない場合は、追加します。
    "oauth2AllowImplicitFlow": true,
    
  14. 保存 を選択します。

リソース所有者のユーザー フローを作成する

  1. Azure AD B2C テナントの外部 ID ユーザー フロー管理者として Azure portal にサインインします。
  2. 複数のテナントにアクセスできる場合、上部のメニューの [設定] アイコンを選択し、[ディレクトリとサブスクリプション] メニューからお使いの Azure AD B2C テナントに切り替えます。
  3. Azure portal で、 [Azure AD B2C] を検索して選択します。
  4. [ ユーザー フロー] を選択し、[ 新しいユーザー フロー] を選択します。
  5. [ リソース所有者のパスワード資格情報 (ROPC) を使用してサインインする] を選択します。
  6. [ バージョン] で、[ プレビュー ] が選択されていることを確認し、[ 作成] を選択します。
  7. ROPC_Auth など、ユーザー フローの名前を指定します。
  8. [ アプリケーション要求] で、[ 詳細を表示] を選択します。
  9. 表示名、電子メール アドレス、ID プロバイダーなど、アプリケーションに必要なアプリケーション要求を選択します。
  10. OK を選択し、作成を選択します。

前提条件

まだ使用していない場合は、「 Active Directory B2C のカスタム ポリシーの使用を開始する」でカスタム ポリシー スターター パックを使用する方法について説明します。

リソース所有者ポリシーを作成する

  1. TrustFrameworkExtensions.xml ファイルを開きます。

  2. BuildingBlocks 要素の下で ClaimsSchema 要素を見つけ、次の要求の種類を追加します。

    <ClaimsSchema>
      <ClaimType Id="logonIdentifier">
        <DisplayName>User name or email address that the user can use to sign in</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="resource">
        <DisplayName>The resource parameter passes to the ROPC endpoint</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokenIssuedOnDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokensValidFromDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
    
  3. ClaimsSchema の後に、ClaimsTransformations 要素とその子要素を BuildingBlocks 要素に追加します。

    <ClaimsTransformations>
      <ClaimsTransformation Id="CreateSubjectClaimFromObjectID" TransformationMethod="CreateStringClaim">
        <InputParameters>
          <InputParameter Id="value" DataType="string" Value="Not supported currently. Use oid claim." />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="sub" TransformationClaimType="createdClaim" />
        </OutputClaims>
      </ClaimsTransformation>
    
      <ClaimsTransformation Id="AssertRefreshTokenIssuedLaterThanValidFromDate" TransformationMethod="AssertDateTimeIsGreaterThan">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" TransformationClaimType="leftOperand" />
          <InputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" TransformationClaimType="rightOperand" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="AssertIfEqualTo" DataType="boolean" Value="false" />
          <InputParameter Id="AssertIfRightOperandIsNotPresent" DataType="boolean" Value="true" />
        </InputParameters>
      </ClaimsTransformation>
    </ClaimsTransformations>
    
  4. DisplayNameLocal Account SignIn 要素を見つけて、次の技術プロファイルを追加します。

    <TechnicalProfile Id="ResourceOwnerPasswordCredentials-OAUTH2">
      <DisplayName>Local Account SignIn</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <Metadata>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
        <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
        <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>
        <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
        <Item Key="ValidTokenIssuerPrefixes">https://sts.windows.net/</Item>
        <Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item>
        <Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item>
        <Item Key="response_types">id_token</Item>
        <Item Key="response_mode">query</Item>
        <Item Key="scope">email openid</Item>
        <Item Key="grant_type">password</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="logonIdentifier" PartnerClaimType="username" Required="true" DefaultValue="{OIDC:Username}"/>
        <InputClaim ClaimTypeReferenceId="password" Required="true" DefaultValue="{OIDC:Password}" />
        <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
        <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
        <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" />
        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    

    client_idDefaultValue を、前提条件のチュートリアルで作成した ProxyIdentityExperienceFramework アプリケーションのアプリケーション ID に置き換えます。 次に、resource_idDefaultValue を、前提条件のチュートリアルで作成した IdentityExperienceFramework アプリケーションのアプリケーション ID に置き換えます。

  5. 技術プロファイルを含む次の ClaimsProvider 要素を ClaimsProviders 要素に追加します。

    <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AAD-UserReadUsingObjectId-CheckRefreshTokenDate">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertRefreshTokenIssuedLaterThanValidFromDate" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
          </OutputClaimsTransformations>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Session Management</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="SM-RefreshTokenReadAndSetup">
          <DisplayName>Trustframework Policy Engine Refresh Token Setup Technical Profile</DisplayName>
          <Protocol Name="None" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" />
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Token Issuer</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="JwtIssuer">
          <Metadata>
            <!-- Point to the redeem refresh token user journey-->
            <Item Key="RefreshTokenUserJourneyId">ResourceOwnerPasswordCredentials-RedeemRefreshToken</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
  6. UserJourneys 要素とその子要素を TrustFrameworkPolicy 要素に追加します。

    <UserJourney Id="ResourceOwnerPasswordCredentials">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ResourceOwnerFlow" TechnicalProfileReferenceId="ResourceOwnerPasswordCredentials-OAUTH2" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    <UserJourney Id="ResourceOwnerPasswordCredentials-RedeemRefreshToken">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RefreshTokenSetupExchange" TechnicalProfileReferenceId="SM-RefreshTokenReadAndSetup" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="CheckRefreshTokenDateFromAadExchange" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId-CheckRefreshTokenDate" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    
  7. Azure AD B2C テナント の [カスタム ポリシー ] ページで、[ポリシーの アップロード] を選択します。

  8. [ ポリシーが存在する場合は上書きする] を有効にし、 TrustFrameworkExtensions.xml ファイルを参照して選択します。

  9. [アップロード] を選択します。

依存パーティファイルを作成する

次に、作成したユーザージャーニーを開始する信頼できるパーティファイルを更新します。

  1. 作業ディレクトリ SignUpOrSignin.xml ファイルのコピーを作成し、 ROPC_Auth.xmlに名前を変更します。

  2. 新しいファイルを開き、TrustFrameworkPolicyPolicyId 属性の値を一意の値に変更します。 ポリシー ID は、ポリシーの名前です。 たとえば、 B2C_1A_ROPC_Auth

  3. DefaultUserJourneyReferenceId 属性の値をResourceOwnerPasswordCredentialsに変更します。

  4. OutputClaims 要素を変更して、次の要求のみを含めます。

    <OutputClaim ClaimTypeReferenceId="sub" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="displayName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="givenName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="surname" DefaultValue="" />
    
  5. Azure AD B2C テナント の [カスタム ポリシー ] ページで、[ポリシーの アップロード] を選択します。

  6. [ ポリシーが存在する場合は上書きする] を有効にし、 ROPC_Auth.xml ファイルを参照して選択します。

  7. [アップロード] を選択します。

ROPC フローをテストする

お気に入りの API 開発アプリケーションを使用して API 呼び出しを生成し、応答を確認してポリシーをデバッグします。 次の情報を POST 要求の本文として使用して、次の例のような呼び出しを作成します。

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • <tenant-name>を Azure AD B2C テナントの名前に置き換えます。
  • B2C_1A_ROPC_Authを、リソース所有者のパスワード資格情報ポリシーの完全な名前に置き換えます。
価値
ユーザー名 user-account
パスワード password1
grant_type(グラントタイプ) パスワード
範囲 openidの application-id offline_access
クライアントID application-id
レスポンス・タイプ (response_type) トークンid_token
  • user-accountをテナント内のユーザー アカウントの名前に置き換えます。
  • password1をユーザー アカウントのパスワードに置き換えます。
  • application-idを、ROPC_Auth_app登録のアプリケーション ID に置き換えます。
  • Offline_accessは、更新トークンを受け取る場合に省略可能です。

実際の POST 要求は次の例のようになります。

POST /<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.com
Content-Type: application/x-www-form-urlencoded

username=contosouser.outlook.com.ws&password=Passxword1&grant_type=password&scope=openid+00001111-aaaa-2222-bbbb-3333cccc4444+offline_access&client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token+id_token

オフライン アクセスで成功した応答は、次の例のようになります。

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki...",
    "token_type": "Bearer",
    "expires_in": "3600",
    "refresh_token": "eyJraWQiOiJacW9pQlp2TW5pYVc2MUY0TnlfR3REVk1EVFBLbUJLb0FUcWQ1ZWFja1hBIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6Ij...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki..."
}

更新トークンを使用する

ここに示すような POST 呼び出しを作成します。 次の表の情報を要求の本文として使用します。

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • <tenant-name>を Azure AD B2C テナントの名前に置き換えます。
  • B2C_1A_ROPC_Authを、リソース所有者のパスワード資格情報ポリシーの完全な名前に置き換えます。
価値
grant_type(グラントタイプ) リフレッシュ トークン (refresh_token)
レスポンス・タイプ (response_type) IDトークン (id_token)
クライアントID application-id
リソース application-id
リフレッシュ トークン (refresh_token) refresh-token
  • application-idを、ROPC_Auth_app登録のアプリケーション ID に置き換えます。
  • refresh-tokenを、前の応答で返されたrefresh_tokenに置き換えます。

成功した応答は次の例のようになります。

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhT...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQn...",
    "token_type": "Bearer",
    "not_before": 1533672990,
    "expires_in": 3600,
    "expires_on": 1533676590,
    "resource": "bef2222d56-552f-4a5b-b90a-1988a7d634c3",
    "id_token_expires_in": 3600,
    "profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiI1MTZmYzA2NS1mZjM2LTRiOTMtYWE1YS1kNmVlZGE3Y2JhYzgiLCJzdWIiOm51bGwsIm5hbWUiOiJEYXZpZE11IiwicHJlZmVycmVkX3VzZXJuYW1lIjpudWxsLCJpZHAiOiJMb2NhbEFjY291bnQifQ",
    "refresh_token": "eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAi...",
    "refresh_token_expires_in": 1209600
}

トラブルシューティング

指定されたアプリケーションは、"OAuth" 暗黙的フローを許可するように構成されていません

  • 現象 - ROPC フローを実行し、次のメッセージが表示されます: AADB2C90057: 指定されたアプリケーションは、"OAuth" 暗黙的フローを許可するように構成されていません
  • 考えられる原因 - 暗黙的なフローは、アプリケーションに対して許可されていません。
  • 解決策: Azure AD B2C で アプリ登録 を作成する場合は、アプリケーション マニフェストを手動で編集し、 oauth2AllowImplicitFlow プロパティの値を trueに設定する必要があります。 oauth2AllowImplicitFlow プロパティを構成した後、変更が有効になるまで数分 (通常は 5 分以内) かかることがあります。

ネイティブ SDK または App-Auth を使用する

Azure AD B2C は、パブリック クライアント リソース所有者のパスワード資格情報の OAuth 2.0 標準を満たしており、ほとんどのクライアント SDK と互換性がある必要があります。 最新の ベスト プラクティスの実装については、OAuth 2.0 用 Native App SDK と OpenID Connect に関するページを参照してください。