次の方法で共有


Azure Active Directory B2C カスタム ポリシーを使用してユーザー入力を収集して操作する

重要

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

Azure Active Directory B2C (Azure AD B2C) カスタム ポリシーを使用すると、ユーザー入力を収集できます。 その後、組み込みのメソッドを使用して、ユーザー入力を操作できます。

この記事では、グラフィカル ユーザー インターフェイスを使用してユーザー入力を収集するカスタム ポリシーを記述する方法について説明します。 次に、入力にアクセスし、その後処理し、最後に JWT で要求として返します。 このタスクを完了するには、次の手順を実行します。

  • 主張を宣言する。 要求は、Azure AD B2C ポリシーの実行中にデータの一時的なストレージを提供します。 名、姓、またはユーザーまたは他のシステムから取得したその他の要求など、ユーザーに関する情報を格納できます。 要求の詳細については、 Azure AD B2C カスタム ポリシーの概要を参照してください。

  • 技術プロファイルを定義します。 技術プロファイルは、さまざまな種類のパーティと通信するためのインターフェイスを提供します。 たとえば、ユーザーと対話してデータを収集できます。

  • 要求変換を構成します。これは、宣言する要求を操作するために使用します。

  • コンテンツ定義を構成します。 コンテンツ定義は、読み込むユーザー インターフェイスを定義します。 後でカスタマイズした独自の HTML コンテンツを提供することで 、ユーザー インターフェイス をカスタマイズできます。

  • Self-Asserted 技術プロファイルと DisplayClaims を使用して、ユーザーに対するユーザー インターフェイスを構成して表示します。

  • オーケストレーション手順を使用して、特定のシーケンスで技術プロファイルを呼び出します。

前提条件

この記事は、 Azure Active Directory B2C での独自のカスタム ポリシーの作成と実行に関するハウツー ガイド シリーズの一部です。 最初の記事からこのシリーズを開始することをお勧めします。

手順 1 - 要求を宣言する

objectIdメッセージと共に追加の要求を宣言します。

  1. VS Code で、 ContosoCustomPolicy.XML ファイルを開きます。

  2. ClaimsSchema セクションで、次の ClaimType 宣言を追加します。

        <ClaimType Id="givenName">
            <DisplayName>Given Name</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Your given name (also known as first name).</UserHelpText>
            <UserInputType>TextBox</UserInputType>
        </ClaimType>
    
        <ClaimType Id="surname">
            <DisplayName>Surname</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Your surname (also known as family name or last name).</UserHelpText>
            <UserInputType>TextBox</UserInputType>
        </ClaimType>
        <ClaimType Id="displayName">
            <DisplayName>Display Name</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>Your display name.</UserHelpText>
            <UserInputType>TextBox</UserInputType>
        </ClaimType>
    

givenNamesurnamedisplayName の 3 つの要求の種類を宣言しました。 これらの宣言には、 DataTypeUserInputType 、および DisplayName 要素が含まれます。

  • DataType は、要求が保持する値のデータ型を指定します。 DataType 要素がサポートするデータ型の詳細について説明します。
  • UserInputType は、ユーザーから要求の値を収集する場合に、ユーザー インターフェイスに表示される UI コントロールを指定します。 Azure AD B2C でサポートされるユーザー入力の種類の詳細について説明します。
  • DisplayName は、ユーザーから要求の値を収集する場合に、ユーザー インターフェイスに表示される UI コントロールのラベルを指定します。

手順 2 - 要求変換を定義する

ClaimsTransformation には、特定の要求を別の要求に変換するために使用する関数が含まれています。 たとえば、文字列要求を小文字から大文字に変更できます。 Azure AD B2C でサポートされる要求変換の詳細について説明します。

  1. ContosoCustomPolicy.XML ファイルで、<ClaimsTransformations> セクションの子としてBuildingBlocks要素を追加します。

        <ClaimsTransformations>
    
        </ClaimsTransformations>
    
  2. ClaimsTransformations要素内に次のコードを追加します。

        <ClaimsTransformation Id="GenerateRandomObjectIdTransformation" TransformationMethod="CreateRandomString">
            <InputParameters>
            <InputParameter Id="randomGeneratorType" DataType="string" Value="GUID"/>
            </InputParameters>
            <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="outputClaim"/>
            </OutputClaims>
        </ClaimsTransformation>
    
        <ClaimsTransformation Id="CreateDisplayNameTransformation" TransformationMethod="FormatStringMultipleClaims">
            <InputClaims>
            <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="inputClaim1"/>
            <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="inputClaim2"/>
            </InputClaims>
            <InputParameters>
            <InputParameter Id="stringFormat" DataType="string" Value="{0} {1}"/>
            </InputParameters>
            <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="outputClaim"/>
            </OutputClaims>
        </ClaimsTransformation>
    
        <ClaimsTransformation Id="CreateMessageTransformation" TransformationMethod="FormatStringClaim">
            <InputClaims>
            <InputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="inputClaim"/>
            </InputClaims>
            <InputParameters>
            <InputParameter Id="stringFormat" DataType="string" Value="Hello {0}"/>
            </InputParameters>
            <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="message" TransformationClaimType="outputClaim"/>
            </OutputClaims>
        </ClaimsTransformation> 
    

    次の 3 つの要求変換を構成しました。

    • GenerateRandomObjectIdTransformation は、 CreateRandomString メソッドで指定されたランダムな文字列を生成します。 objectId 要求は、OutputClaim要素で指定された、生成された文字列で更新されます。

    • CreateDisplayNameTransformation、givenNamesurnameform displayName に連結します。

    • CreateMessageTransformation、HellodisplayName を連結してメッセージを形成 します

手順 3 - コンテンツ定義を構成する

ContentDefinitions を使用すると、ユーザーに表示する Web ページのレイアウトを制御する HTML テンプレートへの URL を指定できます。 サインイン、サインアップ、パスワードリセット、エラー ページなど、各ステップに対して特定のユーザー インターフェイスを指定できます。

コンテンツ定義を追加するには、BuildingBlocks ファイルのセクションContosoCustomPolicy.XML次のコードを追加します。

    <ContentDefinitions>
        <ContentDefinition Id="SelfAssertedContentDefinition">
            <LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri>
            <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
            <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.7</DataUri>
        </ContentDefinition>
    </ContentDefinitions>

手順 4 - 技術プロファイルを構成する

カスタム ポリシーでは、 TechnicalProfile は機能を実装する要素です。 要求と要求変換を定義したので、定義を実行するには技術プロファイルが必要です。 技術プロファイルは、 ClaimsProvider 要素内で宣言されます。

Azure AD B2C には、一連の技術プロファイルが用意されています。 各技術プロファイルは、特定のロールを実行します。 たとえば、 REST 技術プロファイル を使用して、サービス エンドポイントへの HTTP 呼び出しを行います。 要求変換技術プロファイルを使用して、要求変換で定義した操作を実行できます。 Azure AD B2C カスタム ポリシーによって提供される 技術プロファイルの種類 について説明します。

要求の値を設定する

objectIddisplayName、およびメッセージ要求の値を設定するには、GenerateRandomObjectIdTransformationCreateDisplayNameTransformation、および CreateMessageTransformation 要求変換を実行する技術プロファイルを構成します。 要求変換は、 OutputClaimsTransformations 要素で定義された順序で実行されます。 たとえば、最初に表示名を作成し、次にメッセージを作成します。

  1. ClaimsProvider セクションの子として、次のClaimsProvidersを追加します。

        <ClaimsProvider>
    
            <DisplayName>Technical Profiles to generate claims</DisplayName>
        </ClaimsProvider>
    
    
  2. objectIddisplayNameおよびメッセージ要求の値を設定するには、先ほど作成したClaimsProvider要素内に次のコードを追加します。

        <!--<ClaimsProvider>-->
            <TechnicalProfiles>
                <TechnicalProfile Id="ClaimGenerator">
                    <DisplayName>Generate Object ID, displayName and message Claims Technical Profile.</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectId"/>
                        <OutputClaim ClaimTypeReferenceId="displayName"/>
                        <OutputClaim ClaimTypeReferenceId="message"/>
                    </OutputClaims>
                    <OutputClaimsTransformations>
                        <OutputClaimsTransformation ReferenceId="GenerateRandomObjectIdTransformation"/>
                        <OutputClaimsTransformation ReferenceId="CreateDisplayNameTransformation"/>
                        <OutputClaimsTransformation ReferenceId="CreateMessageTransformation"/>
                    </OutputClaimsTransformations>
                </TechnicalProfile>
            </TechnicalProfiles>
        <!--</ClaimsProvider>-->
    

ユーザー入力を収集する

givenNamesurname から displayName 要求を生成するため、ユーザー入力として収集する必要があります。 ユーザー入力を収集するには、 セルフアサートと呼ばれる技術プロファイルの種類を使用します。 セルフアサート技術プロファイルを構成する場合は、セルフアサート技術プロファイルがユーザー インターフェイスの表示を担当するため、コンテンツ定義を参照する必要があります。

  1. ClaimsProvider セクションの子として、次のClaimsProvidersを追加します。

        <ClaimsProvider>
    
            <DisplayName>Technical Profiles to collect user's details </DisplayName>
        </ClaimsProvider>
    
  2. 作成した ClaimsProvider 要素内に次のコードを追加します。

        <TechnicalProfiles>
            <TechnicalProfile Id="UserInformationCollector">
                <DisplayName>Collect User Input Technical Profile</DisplayName>
                <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                <Metadata>
                    <Item Key="ContentDefinitionReferenceId">SelfAssertedContentDefinition</Item>
                </Metadata>
                <DisplayClaims>
                    <DisplayClaim ClaimTypeReferenceId="givenName" Required="true"/>
                    <DisplayClaim ClaimTypeReferenceId="surname" Required="true"/>
                </DisplayClaims>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="givenName"/>
                    <OutputClaim ClaimTypeReferenceId="surname"/>
                </OutputClaims>
            </TechnicalProfile>
        </TechnicalProfiles>
    

    givenName 要求と要求の 2 つの表示要求に注目してください。 どちらの要求も必須としてマークされるため、ユーザーは表示されるフォームを送信する前に値を入力する必要があります。 要求は、 DisplayClaims 要素で定義されている順序 ( Given NameSurname など) で画面に表示されます。

手順 5 - ユーザー体験を定義する

ユーザー体験を使用して、技術プロファイルを呼び出す順序を定義します。 OrchestrationSteps要素を使用して、ユーザー体験のステップを指定します。

HelloWorldJourney ユーザー体験の既存の内容を次のコードに置き換えます。

    <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="GetUserInformationClaimsExchange" TechnicalProfileReferenceId="UserInformationCollector"/>
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
            <ClaimsExchanges>
                <ClaimsExchange Id="GetMessageClaimsExchange" TechnicalProfileReferenceId="ClaimGenerator"/>
            </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer"/>
    </OrchestrationSteps>

オーケストレーションの手順に従って、ユーザー入力を収集し、 objectIddisplayNameおよびメッセージ 要求の値を設定し、最後に JWT を送信します。

手順 6 - 証明書利用者を更新する

OutputClaims セクションのRelyingParty要素の内容を次のコードに置き換えます。

    <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
    <OutputClaim ClaimTypeReferenceId="displayName"/>
    <OutputClaim ClaimTypeReferenceId="message"/>

手順 6. を完了すると、ContosoCustomPolicy.XML ファイルは次のコードのようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" 
    PolicySchemaVersion="0.3.0.0" TenantId="yourtenant.onmicrosoft.com" 
    PolicyId="B2C_1A_ContosoCustomPolicy" 
    PublicPolicyUri="http://yourtenant.onmicrosoft.com/B2C_1A_ContosoCustomPolicy">
    
    <BuildingBlocks>
        <ClaimsSchema>
            <ClaimType Id="objectId">
                <DisplayName>unique object Id for subject of the claims being returned</DisplayName>
                <DataType>string</DataType>
            </ClaimType>
            <ClaimType Id="message">
                <DisplayName>Will hold Hello World message</DisplayName>
                <DataType>string</DataType>
            </ClaimType>

            <ClaimType Id="givenName">
                <DisplayName>Given Name</DisplayName>
                <DataType>string</DataType>
                <UserHelpText>Your given name (also known as first name).</UserHelpText>
                <UserInputType>TextBox</UserInputType>
            </ClaimType>
            <ClaimType Id="surname">
                <DisplayName>Surname</DisplayName>
                <DataType>string</DataType>
                <UserHelpText>Your surname (also known as family name or last name).</UserHelpText>
                <UserInputType>TextBox</UserInputType>
            </ClaimType>
            <ClaimType Id="displayName">
                <DisplayName>Display Name</DisplayName>
                <DataType>string</DataType>
                <UserHelpText>Your display name.</UserHelpText>
                <UserInputType>TextBox</UserInputType>
            </ClaimType>
        </ClaimsSchema>
        <ClaimsTransformations>
            <ClaimsTransformation Id="GenerateRandomObjectIdTransformation" TransformationMethod="CreateRandomString">
                <InputParameters>
                    <InputParameter Id="randomGeneratorType" DataType="string" Value="GUID"/>
                </InputParameters>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="outputClaim"/>
                </OutputClaims>
            </ClaimsTransformation>

            <ClaimsTransformation Id="CreateDisplayNameTransformation" TransformationMethod="FormatStringMultipleClaims">
                <InputClaims>
                    <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="inputClaim1"/>
                    <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="inputClaim2"/>
                </InputClaims>
                <InputParameters>
                    <InputParameter Id="stringFormat" DataType="string" Value="{0} {1}"/>
                </InputParameters>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="outputClaim"/>
                </OutputClaims>
            </ClaimsTransformation>

            <ClaimsTransformation Id="CreateMessageTransformation" TransformationMethod="FormatStringClaim">
                <InputClaims>
                    <InputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="inputClaim"/>
                </InputClaims>
                <InputParameters>
                    <InputParameter Id="stringFormat" DataType="string" Value="Hello {0}"/>
                </InputParameters>
                <OutputClaims>
                    <OutputClaim ClaimTypeReferenceId="message" TransformationClaimType="outputClaim"/>
                </OutputClaims>
            </ClaimsTransformation> 
        </ClaimsTransformations>
        <ContentDefinitions>
            <ContentDefinition Id="SelfAssertedContentDefinition">
                <LoadUri>~/tenant/templates/AzureBlue/selfAsserted.cshtml</LoadUri>
                <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
                <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.7</DataUri>
            </ContentDefinition>
        </ContentDefinitions>
    </BuildingBlocks>
    <!--Claims Providers Here-->
    <ClaimsProviders>
        <ClaimsProvider>
            <DisplayName>Token Issuer</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="JwtIssuer">
                    <DisplayName>JWT Issuer</DisplayName>
                    <Protocol Name="None"/>
                    <OutputTokenFormat>JWT</OutputTokenFormat>
                    <Metadata>
                        <Item Key="client_id">{service:te}</Item>
                        <Item Key="issuer_refresh_token_user_identity_claim_type">objectId</Item>
                        <Item Key="SendTokenResponseBodyWithJsonNumbers">true</Item>
                    </Metadata>
                    <CryptographicKeys>
                        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer"/>
                        <Key Id="issuer_refresh_token_key" StorageReferenceId="B2C_1A_TokenEncryptionKeyContainer"/>
                    </CryptographicKeys>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>

        <ClaimsProvider>
            <DisplayName>Trustframework Policy Engine TechnicalProfiles</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="TpEngine_c3bd4fe2-1775-4013-b91d-35f16d377d13">
                    <DisplayName>Trustframework Policy Engine Default Technical Profile</DisplayName>
                    <Protocol Name="None"/>
                    <Metadata>
                        <Item Key="url">{service:te}</Item>
                    </Metadata>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>

        <ClaimsProvider>
            <DisplayName>Claim Generator Technical Profiles</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="ClaimGenerator">
                    <DisplayName>Generate Object ID, displayName and  message Claims Technical Profile.</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectId"/>
                        <OutputClaim ClaimTypeReferenceId="displayName"/>
                        <OutputClaim ClaimTypeReferenceId="message"/>
                    </OutputClaims>
                    <OutputClaimsTransformations>
                        <OutputClaimsTransformation ReferenceId="GenerateRandomObjectIdTransformation"/>
                        <OutputClaimsTransformation ReferenceId="CreateDisplayNameTransformation"/>
                        <OutputClaimsTransformation ReferenceId="CreateMessageTransformation"/>
                    </OutputClaimsTransformations>
                </TechnicalProfile>
            </TechnicalProfiles>            
        </ClaimsProvider>

        <ClaimsProvider>
            <DisplayName>Technical Profiles to collect user's details</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="UserInformationCollector">
                    <DisplayName>Collect User Input Technical Profile</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                    <Metadata>
                        <Item Key="ContentDefinitionReferenceId">SelfAssertedContentDefinition</Item>
                    </Metadata>
                    <DisplayClaims>
                        <DisplayClaim ClaimTypeReferenceId="givenName" Required="true"/>
                        <DisplayClaim ClaimTypeReferenceId="surname" Required="true"/>
                    </DisplayClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="givenName"/>
                        <OutputClaim ClaimTypeReferenceId="surname"/>
                    </OutputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>

    <UserJourneys>
        <UserJourney Id="HelloWorldJourney">
            <OrchestrationSteps>
                <OrchestrationStep Order="1" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="GetUserInformationClaimsExchange" TechnicalProfileReferenceId="UserInformationCollector"/>
                    </ClaimsExchanges>
                </OrchestrationStep>
                <OrchestrationStep Order="2" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="GetMessageClaimsExchange" TechnicalProfileReferenceId="ClaimGenerator"/>
                    </ClaimsExchanges>
                </OrchestrationStep>
                <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer"/>
            </OrchestrationSteps>
        </UserJourney>
    </UserJourneys>

    <RelyingParty><!-- 
            Relying Party Here that's your policy’s entry point
            Specify the User Journey to execute 
            Specify the claims to include in the token that is returned when the policy runs
        -->
        <DefaultUserJourney ReferenceId="HelloWorldJourney"/>
        <TechnicalProfile Id="HelloWorldPolicyProfile">
            <DisplayName>Hello World Policy Profile</DisplayName>
            <Protocol Name="OpenIdConnect"/>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
                <OutputClaim ClaimTypeReferenceId="displayName"/>
                <OutputClaim ClaimTypeReferenceId="message"/>
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub"/>
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

まだ行っていない場合は、 yourtenant をテナント名のサブドメイン部分 ( contoso など) に置き換えます。 テナント名を取得する方法について説明します。

手順 7 - カスタム ポリシー ファイルをアップロードする

「カスタム ポリシー ファイルのアップロード」の手順に従います。 ポータルに既に存在するファイルと同じ名前のファイルをアップロードする場合は、[ カスタム ポリシーが既に存在する場合は上書きする] を選択してください。

手順 8 - カスタム ポリシーをテストする

  1. [ カスタム ポリシー] で、[ B2C_1A_CONTOSOCUSTOMPOLICY] を選択します。

  2. カスタム ポリシーの概要ページの [ アプリケーションの選択 ] で、以前に登録した Webapp1 などの Web アプリケーションを選択します。 [ 応答 URL の選択 ] の値が [https://jwt.ms] に設定されていることを確認します。

  3. [ 今すぐ実行 ] ボタンを選択します。

  4. 「指定された名前」と「姓」と入力し、[続行] を選択します。

    カスタム ポリシーでユーザー入力を受け入れるスクリーンショット。

ポリシーの実行が完了すると、 https://jwt.msにリダイレクトされ、デコードされた JWT が表示されます。 次の JWT スニペットのようになります。

    {
      "typ": "JWT",
      "alg": "RS256",
      "kid": "pxLOMWFg...."
    }.{
      ...
      "sub": "c7ae4515-f7a7....",
      ...
      "acr": "b2c_1a_contosocustompolicy",
      ...
      "name": "Maurice Paulet",
      "message": "Hello Maurice Paulet"
    }.[Signature]

次に、次の情報を確認します。