Dela via


Samla in och ändra användarindata med hjälp av en anpassad azure Active Directory B2C-princip

Med anpassade principer för Azure Active Directory B2C (Azure AD B2C) kan du samla in användarindata. Du kan sedan använda inbyggda metoder för att ändra användarindata.

I den här artikeln får du lära dig hur du skriver en anpassad princip som samlar in användarindata via ett grafiskt användargränssnitt. Sedan kommer du åt indata, bearbetar dem och returnerar dem slutligen som anspråk i en JWT-token. För att slutföra den här uppgiften gör du följande:

  • Deklarera anspråk. Ett anspråk ger tillfällig lagring av data under en Azure AD B2C-principkörning. Den kan lagra information om användaren, till exempel förnamn, efternamn eller andra anspråk som hämtats från användaren eller andra system. Du kan lära dig mer om anspråk i översikten över anpassad princip i Azure AD B2C.

  • Definiera tekniska profiler. En teknisk profil tillhandahåller ett gränssnitt för att kommunicera med olika typer av parter. Du kan till exempel interagera med användaren för att samla in data.

  • Konfigurera anspråksomvandlingar som du använder för att manipulera de anspråk som du deklarerar.

  • Konfigurera innehållsdefinitioner. En innehållsdefinition definierar användargränssnittet som ska läsas in. Senare kan du anpassa användargränssnittet genom att tillhandahålla ditt eget anpassade HTML-innehåll.

  • Konfigurera och visa användargränssnitt för användaren med hjälp av självsäkra tekniska profiler och DisplayClaims.

  • Anropa tekniska profiler i en viss sekvens med hjälp av Orkestreringssteg.

Förutsättningar

Kommentar

Den här artikeln är en del av guideserien Skapa och köra egna anpassade principer i Azure Active Directory B2C. Vi rekommenderar att du startar den här serien från den första artikeln.

Steg 1 – Deklarera anspråk

Deklarera ytterligare anspråk tillsammans med objectId och meddelande:

  1. Öppna filen i ContosoCustomPolicy.XML VS Code.

  2. I avsnittet ClaimsSchema lägger du till följande ClaimType-deklarationer :

        <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>
    

Vi har deklarerat tre anspråkstyper, givenName, efternamn och displayName. Dessa deklarationer omfattar DataType, UserInputType och DisplayName element:

  • DataType anger datatypen för det värde som anspråken innehåller. Läs mer om de datatyper som DataType-elementen stöder.
  • UserInputType anger den användargränssnittskontroll som visas i användargränssnittet om du vill samla in värdet för anspråket från användaren. Läs mer om de användarindatatyper som Azure AD B2C stöder.
  • DisplayName anger etiketten för användargränssnittskontrollen som visas i användargränssnittet om du vill samla in värdet för anspråket från användaren.

Steg 2 – Definiera anspråkstransformeringar

En ClaimsTransformation innehåller en funktion som du använder för att konvertera ett visst anspråk till ett annat. Du kan till exempel ändra ett stränganspråk från gemener till versaler. Läs mer om anspråkstransformeringar som stöds av Azure AD B2C.

  1. ContosoCustomPolicy.XML I filen lägger du till ett <ClaimsTransformations> element som underordnat i BuildingBlocks avsnittet.

        <ClaimsTransformations>
    
        </ClaimsTransformations>
    
  2. Lägg till följande kod i elementet 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> 
    

    Vi har konfigurerat tre anspråkstransformeringar:

    • GenerateRandomObjectIdTransformation genererar en slumpmässig sträng enligt metoden CreateRandomString . ObjectId-anspråket uppdateras med den genererade strängen som anges av elementetOutputClaim.

    • CreateDisplayNameTransformation sammanfogar givenName och efternamn för att bilda displayName.

    • CreateMessageTransformation sammanfogar Hello och displayName för att skapa ett meddelande.

Steg 3 – Konfigurera innehållsdefinitioner

Med ContentDefinitions kan du ange URL till HTML-mallar som styr layouten för de webbsidor som du visar för användarna. Du kan ange specifika användargränssnitt för varje steg, till exempel inloggning eller registrering, lösenordsåterställning eller felsidor.

Om du vill lägga till innehållsdefinition lägger du till följande kod i BuildingBlocks avsnittet i ContosoCustomPolicy.XML filen:

    <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>

Steg 4 – Konfigurera tekniska profiler

I en anpassad princip är en TechnicalProfile det element som implementerar funktioner. Nu när du har definierat anspråks- och anspråkstransformeringar behöver du tekniska profiler för att köra dina definitioner. En teknisk profil deklareras i elementen ClaimsProvider .

Azure AD B2C tillhandahåller en uppsättning tekniska profiler. Varje teknisk profil utför en specifik roll. Du kan till exempel använda en teknisk REST-profil för att göra ett HTTP-anrop till en tjänstslutpunkt. Du kan använda en teknisk profil för anspråkstransformering för att köra den åtgärd som du definierar i en anspråkstransformering. Läs mer om de typer av tekniska profiler som azure AD B2C-anpassade principer tillhandahåller.

Ange värden för dina anspråk

Om du vill ange värden för objectId, displayName och meddelandeanspråk konfigurerar du en teknisk profil som kör anspråksomvandlingarna GenerateRandomObjectIdTransformation, CreateDisplayNameTransformation och CreateMessageTransformation. Anspråkstransformeringar körs av den ordning som definieras i elementet OutputClaimsTransformations . Den skapar till exempel först visningsnamnet och sedan meddelandet.

  1. Lägg till följande ClaimsProvider som underordnad i ClaimsProviders avsnittet.

        <ClaimsProvider>
    
            <DisplayName>Technical Profiles to generate claims</DisplayName>
        </ClaimsProvider>
    
    
  2. Om du vill ange värden för objectId, displayName och meddelandeanspråk lägger du till följande kod i elementet ClaimsProvider som du nyss skapade:

        <!--<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>-->
    

Samla in användarindata

Du genererar displayName-anspråket från givenNamn och efternamn, så du måste samla in sedan som användarindata. Om du vill samla in en användarindata använder du en typ av teknisk profil med namnet Self-Asserted. När du konfigurerar en självsäkrad teknisk profil måste du referera till innehållsdefinitionerna som en självsäkrad teknisk profil som ansvarar för att visa ett användargränssnitt.

  1. Lägg till följande ClaimsProvider som underordnad i ClaimsProviders avsnittet.

        <ClaimsProvider>
    
            <DisplayName>Technical Profiles to collect user's details </DisplayName>
        </ClaimsProvider>
    
  2. Lägg till följande kod i elementet ClaimsProvider som du nyss skapade:

        <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>
    

    Observera de två visningsanspråken för angivetNamn och efternamnsanspråk . Båda anspråken markeras som obligatoriska, så användaren måste ange värdena innan de skickar formuläret som visas för dem. Anspråken visas på skärmen i den ordning som definieras i elementet DisplayClaims, till exempel förnamn och sedan efternamn.

Steg 5 – Definiera användarresor

Du använder användarresor för att definiera i vilken ordning de tekniska profilerna anropas. Du använder elementet OrchestrationSteps för att ange stegen i en användarresa.

Ersätt det befintliga innehållet i HelloWorldJourney användarresan med följande kod:

    <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>

Enligt orkestreringsstegen samlar vi in användarindata, anger värden för objectId, displayName och meddelandeanspråk och skickar slutligen Jwt-token.

Steg 6 – Uppdatera förlitande part

Ersätt innehållet i elementet OutputClaims i RelyingParty avsnittet med följande kod:

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

När du har slutfört steg 6ContosoCustomPolicy.XML bör filen se ut ungefär så här:

<?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>

Om du inte redan har gjort det ersätter yourtenant du med underdomändelen av klientorganisationens namn, till exempel contoso. Lär dig hur du hämtar ditt klientnamn.

Steg 3 – Ladda upp anpassad principfil

Följ stegen i Ladda upp anpassad principfil. Om du laddar upp en fil med samma namn som den som redan finns i portalen kontrollerar du att du väljer Skriv över den anpassade principen om den redan finns.

Steg 4 – Testa den anpassade principen

  1. Under Anpassade principer väljer du B2C_1A_CONTOSOCUSTOMPOLICY.

  2. För Välj program på översiktssidan för den anpassade principen väljer du webbprogrammet, till exempel webapp1 som du tidigare registrerade. Kontrollera att värdet Välj svars-URL är inställt påhttps://jwt.ms.

  3. Välj knappen Kör nu .

  4. Ange Förnamn och Efternamn och välj sedan Fortsätt.

    screenshot of accepting user inputs in custom policy.

När principen har slutfört körningen omdirigeras du till https://jwt.msoch du ser en avkodad JWT-token. Det ser ut ungefär som följande JWT-tokenfragment:

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

Nästa steg

Lär dig sedan: