Dela via


Verifiera användarindata med hjälp av en anpassad Azure Active Directory B2C-princip

Viktigt!

Från och med den 1 maj 2025 är Azure AD B2C inte längre tillgängligt att köpa för nya kunder. Läs mer i våra vanliga frågor och svar.

Med anpassad princip för Azure Active Directory B2C (Azure AD B2C) kan du inte bara göra användarindata obligatoriska utan även verifiera dem. Du kan markera användarindata som obligatorisk, till exempel <DisplayClaim ClaimTypeReferenceId="givenName" Required="true"/>, men det betyder inte att dina användare kommer att ange giltiga data. Azure AD B2C tillhandahåller olika sätt att verifiera en användares indata. I den här artikeln får du lära dig hur du skriver en anpassad princip som samlar in användarindata och validerar dem med hjälp av följande metoder:

  • Begränsa de data som en användare anger genom att ange en lista med alternativ att välja mellan. Den här metoden använder uppräknade värden som du lägger till när du deklarerar ett anspråk.

  • Definiera ett mönster som en användarinmatning måste matcha. Den här metoden använder reguljära uttryck som du lägger till när du deklarerar ett anspråk.

  • Definiera en uppsättning regler och kräva att en användarinmatning följer en eller flera av reglerna. Den här metoden använder predikat som du lägger till när du deklarerar ett anspråk.

  • Använd den särskilda anspråkstypen reenterPassword för att verifiera att användaren har angett sitt lösenord på nytt under insamlingen av användarindata.

  • Konfigurera en teknisk valideringsprofil som definierar komplexa affärsregler som inte är möjliga att definiera på anspråksdeklarationsnivå. Du kan till exempel ta emot en användarinmatning som måste verifieras mot ett värde eller en uppsättning värden i ett annat anspråk.

Förutsättningar

Anmärkning

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

Steg 1 – Verifiera användarindata genom att begränsa alternativen för användarinmatning

Om du känner till alla möjliga värden som en användare kan ange för en viss indata kan du ange en begränsad uppsättning värden som en användare måste välja mellan. Du kan använda DropdownSingleSelect, CheckboxMultiSelect och RadioSingleSelectUserInputType för det här ändamålet. I den här artikeln använder du en RadioSingleSelect-indatatyp :

  1. Öppna filen ContosoCustomPolicy.XMLi VS Code.

  2. I -elementet ClaimsSchema i ContosoCustomPolicy.XML filen deklarerar du följande anspråkstyp:

        <ClaimType Id="accountType">
            <DisplayName>Account Type</DisplayName>
            <DataType>string</DataType>
            <UserHelpText>The type of account used by the user</UserHelpText>
            <UserInputType>RadioSingleSelect</UserInputType>
            <Restriction>
                <Enumeration Text="Contoso Employee Account" Value="work" SelectByDefault="true"/>
                <Enumeration Text="Personal Account" Value="personal" SelectByDefault="false"/>
            </Restriction>
        </ClaimType>
    

    Vi har deklarerat accountType-krav. När anspråkets värde samlas in från användaren måste användaren välja antingen Contoso Employee Account för ett värde arbete eller Personligt konto för ett personligt värde.

    Med Azure AD B2C kan du också anpassa din princip till olika språk och tillhandahåller kontotypsbegränsningar för flera språk. Mer information finns i artikeln Lokalisera användargränssnittet i artikeln Lägg till användarattribut.

  3. Leta upp den tekniska profilen med Id="UserInformationCollector" och lägg till accountType-anspråket som visningsanspråk med hjälp av följande kod:

        <DisplayClaim ClaimTypeReferenceId="accountType" Required="true"/>
    
  4. I den tekniska profilen med Id="UserInformationCollector"lägger du till accountType-anspråket som ett utdataanspråk med hjälp av följande kod:

        <OutputClaim ClaimTypeReferenceId="accountType"/>
    
  5. Om du vill inkludera kontotypsanspråket i åtkomsttoken letar du upp elementet RelyingParty och lägger till accountType-anspråket som ett tokenanspråk med hjälp av följande kod:

        <OutputClaim ClaimTypeReferenceId="accountType" />
    

Steg 2 – Verifiera användarindata med hjälp av reguljära uttryck

När det inte går att känna till alla möjliga användarindatavärden i förväg tillåter du användaren att själva mata in data. I det här fallet kan du använda reguljära uttryck (regex) eller mönster för att diktera hur en användarinmatning måste formateras. Ett e-postmeddelande måste till exempel ha symbolen at (@) och en punkt (.) någonstans i texten.

När du lämnar in ett krav kan du med en anpassad policy definiera en regex som måste matcha användarens indata. Du kan också ange ett meddelande som visas för användaren om deras indata inte matchar uttrycket.

  1. Hitta elementet ClaimsSchema och deklarera kravet på e-post med följande kod:

        <ClaimType Id="email">
            <DisplayName>Email Address</DisplayName>
            <DataType>string</DataType>
            <DefaultPartnerClaimTypes>
                <Protocol Name="OpenIdConnect" PartnerClaimType="email"/>
            </DefaultPartnerClaimTypes>
            <UserHelpText>Your email address. </UserHelpText>
            <UserInputType>TextBox</UserInputType>
            <Restriction>
                <Pattern RegularExpression="^[a-zA-Z0-9.!#$%&amp;&apos;^_`{}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" HelpText="Please enter a valid email address something like maurice@contoso.com"/>
            </Restriction>
        </ClaimType>
    
  2. Leta upp den tekniska profilen med Id="UserInformationCollector", och lägg till e-postanspråket som visningsanspråk med användning av följande kod:

        <DisplayClaim ClaimTypeReferenceId="email" Required="true"/>
    
  3. I den tekniska profilen med Id="UserInformationCollector" lägger du till e-post som utdata genom följande kod:

        <OutputClaim ClaimTypeReferenceId="email"/>
    
  4. Leta upp elementet RelyingParty och lägg till e-postmeddelandet som ett tokenanspråk med hjälp av följande kod:

        <OutputClaim ClaimTypeReferenceId="email" />
    

Steg 3 – Verifiera användarindata med hjälp av predikat

Du har använt regex för att verifiera användarindata. Regex har dock en svaghet, d.v.s. felmeddelandet visas tills du korrigerar indata utan att visa det specifika kravet att indata saknas.

Med predikatvalidering kan du åtgärda det här problemet genom att låta dig definiera en uppsättning regler (predikater) och ett oberoende felmeddelande för varje regel. I anpassade principer har ett predikat en inbyggd metod som definierar de kontroller som du vill göra. Du kan till exempel använda metoden IsLengthRange-predikat för att kontrollera om ett användarlösenord ligger inom det intervall med minsta och högsta parametrar (värden) som angetts.

Medan predikat definierar valideringen för att kontrollera mot en anspråkstyp, grupperar PredicateValidations en uppsättning predikat för att bilda en validering av användarinmatning som kan tillämpas på en anspråkstyp. Du kan till exempel skapa en predikatgrupp med validering som validerar olika typer av tillåtna tecken för ett lösenord. Elementen Predicates och PredicateValidations är underordnade element i BuildingBlocks avsnittet i principfilen.

  1. Leta upp elementet ClaimsSchema och deklarera lösenordsanspråket med hjälp av följande kod:

        <ClaimType Id="password">
          <DisplayName>Password</DisplayName>
          <DataType>string</DataType>
          <AdminHelpText>Enter password</AdminHelpText>
          <UserHelpText>Enter password</UserHelpText>
          <UserInputType>Password</UserInputType>
        </ClaimType>
    
  2. Lägg till ett Predicates element som underordnat BuildingBlocks avsnitt med hjälp av följande kod. Du lägger till elementet Predicates under elementet ClaimsSchema :

        <Predicates>
    
        </Predicates>
    
  3. I elementet Predicates definierar du predikat med hjälp av följande kod:

      <Predicate Id="IsLengthBetween8And64" Method="IsLengthRange" HelpText="The password must be between 8 and 64 characters.">
        <Parameters>
          <Parameter Id="Minimum">8</Parameter>
          <Parameter Id="Maximum">64</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="Lowercase" Method="IncludesCharacters" HelpText="a lowercase letter">
        <Parameters>
          <Parameter Id="CharacterSet">a-z</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="Uppercase" Method="IncludesCharacters" HelpText="an uppercase letter">
        <Parameters>
          <Parameter Id="CharacterSet">A-Z</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="Number" Method="IncludesCharacters" HelpText="a digit">
        <Parameters>
          <Parameter Id="CharacterSet">0-9</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="Symbol" Method="IncludesCharacters" HelpText="a symbol">
        <Parameters>
          <Parameter Id="CharacterSet">@#$%^&amp;*\-_+=[]{}|\\:',.?/`~"();!</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="PIN" Method="MatchesRegex" HelpText="The password must be numbers only.">
        <Parameters>
          <Parameter Id="RegularExpression">^[0-9]+$</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="AllowedCharacters" Method="MatchesRegex" HelpText="An invalid character was provided.">
        <Parameters>
          <Parameter Id="RegularExpression">(^([0-9A-Za-z\d@#$%^&amp;*\-_+=[\]{}|\\:',?/`~"();! ]|(\.(?!@)))+$)|(^$)</Parameter>
        </Parameters>
      </Predicate>
    
      <Predicate Id="DisallowedWhitespace" Method="MatchesRegex" HelpText="The password must not begin or end with a whitespace character.">
        <Parameters>
          <Parameter Id="RegularExpression">(^\S.*\S$)|(^\S+$)|(^$)</Parameter>
        </Parameters>
      </Predicate>
    

    Vi har definierat flera regler, som när de sammanställs beskrev ett acceptabelt lösenord. Sedan kan du gruppera predikat för att skapa en uppsättning lösenordsprinciper som du kan använda i din princip.

  4. Lägg till ett PredicateValidations element som underordnat BuildingBlocks avsnitt med hjälp av följande kod. Du lägger till PredicateValidations-elementet som ett underordnat till BuildingBlocks-avsnittet, men efter Predicates-elementet.

        <PredicateValidations>
    
        </PredicateValidations>
    
  5. I elementet PredicateValidations definierar du PredicateValidations med hjälp av följande kod:

        <PredicateValidation Id="SimplePassword">
            <PredicateGroups>
                <PredicateGroup Id="DisallowedWhitespaceGroup">
                    <PredicateReferences>
                        <PredicateReference Id="DisallowedWhitespace"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="AllowedCharactersGroup">
                    <PredicateReferences>
                        <PredicateReference Id="AllowedCharacters"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="LengthGroup">
                    <PredicateReferences>
                        <PredicateReference Id="IsLengthBetween8And64"/>
                    </PredicateReferences>
                </PredicateGroup>
            </PredicateGroups>
        </PredicateValidation>
        <PredicateValidation Id="StrongPassword">
            <PredicateGroups>
                <PredicateGroup Id="DisallowedWhitespaceGroup">
                    <PredicateReferences>
                        <PredicateReference Id="DisallowedWhitespace"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="AllowedCharactersGroup">
                    <PredicateReferences>
                        <PredicateReference Id="AllowedCharacters"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="LengthGroup">
                    <PredicateReferences>
                        <PredicateReference Id="IsLengthBetween8And64"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="CharacterClasses">
                    <UserHelpText>The password must have at least 3 of the following:</UserHelpText>
                    <PredicateReferences MatchAtLeast="3">
                        <PredicateReference Id="Lowercase"/>
                        <PredicateReference Id="Uppercase"/>
                        <PredicateReference Id="Number"/>
                        <PredicateReference Id="Symbol"/>
                    </PredicateReferences>
                </PredicateGroup>
            </PredicateGroups>
        </PredicateValidation>
        <PredicateValidation Id="CustomPassword">
            <PredicateGroups>
                <PredicateGroup Id="DisallowedWhitespaceGroup">
                    <PredicateReferences>
                        <PredicateReference Id="DisallowedWhitespace"/>
                    </PredicateReferences>
                </PredicateGroup>
                <PredicateGroup Id="AllowedCharactersGroup">
                    <PredicateReferences>
                        <PredicateReference Id="AllowedCharacters"/>
                    </PredicateReferences>
                </PredicateGroup>
            </PredicateGroups>
        </PredicateValidation>
    

    Vi har tre definierade predikatvalidering, StrongPassword, CustomPassword och SimplePassword. Beroende på egenskaperna för det lösenord som du vill att användarna ska ange kan du använda valfritt på predikatvalideringarna. I den här artikeln använder vi ett starkt lösenord.

  6. Leta upp deklarationen för anspråkstyp för lösenord och lägg till StrongPassword Predicate Validation strax efter elementdeklarationen UserInputType som den innehåller med hjälp av följande kod:

        <PredicateValidationReference Id="StrongPassword" />
    
  7. Leta upp den tekniska profilen med Id="UserInformationCollector"och lägg till lösenordsanspråket som visningsanspråk med hjälp av följande kod:

        <DisplayClaim ClaimTypeReferenceId="password" Required="true"/>
    
  8. I den tekniska profilen med Id="UserInformationCollector"lägger du till lösenordsanspråket som ett utdataanspråk med hjälp av följande kod:

        <OutputClaim ClaimTypeReferenceId="password"/>
    

Anmärkning

Av säkerhetsskäl lägger vi inte till en användares lösenord som ett anspråk i den token som genereras av din policy. Därför lägger vi inte till lösenordsanspråket i det förlitande partelementet.

Steg 4 – Verifiera lösenord och bekräfta lösenord

Du kan kräva att användarna anger sitt lösenord två gånger som ett sätt att bekräfta att användaren kommer ihåg lösenordet de anger. I det här fallet måste du kontrollera att värdena för de två posterna matchar. Anpassad policy ger ett enkelt sätt att uppnå detta krav. Anspråkstyperna lösenord och reenterPassword anses vara speciella, så när de används för att samla in användarindata verifierar användargränssnittet att användaren har angett sitt lösenord på nytt.

Använd följande steg för att verifiera att lösenordet har angetts på nytt i din anpassade princip:

  1. I avsnittet ClaimsSchema i ContosoCustomPolicy.XML filen deklarerar du reenterPassword-anspråket strax efter lösenordsanspråket med hjälp av följande kod:

        <ClaimType Id="reenterPassword">
            <DisplayName>Confirm new password</DisplayName>
            <DataType>string</DataType>
            <AdminHelpText>Confirm new password</AdminHelpText>
            <UserHelpText>Reenter password</UserHelpText>
            <UserInputType>Password</UserInputType>
        </ClaimType>    
    
  2. För att samla in lösenordsbekräftelse från användaren, leta upp den UserInformationCollector självdeklarerade tekniska profilen och lägg till reenterPassword som ett visningsattribut med hjälp av följande kod:

        <DisplayClaim ClaimTypeReferenceId="reenterPassword" Required="true"/>
    
  3. ContosoCustomPolicy.XML Leta upp den UserInformationCollector självdeklarerade tekniska profilen i filen och lägg till reenterPassword-anspråket som ett utdataanspråk med hjälp av följande kod:

        <OutputClaim ClaimTypeReferenceId="reenterPassword"/>
    

Steg 5 – Ladda upp anpassad principfil

Nu har du skapat din princip för att hantera de tre första metoderna för verifiering av användarindata.

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 Skriva över den anpassade principen om den redan finns.

Steg 6 – Testa den anpassade policyn

  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.

  5. Välj Kontotyp.

  6. För E-postadress anger du ett e-postvärde som inte är väl formaterat, till exempel maurice@contoso.

  7. För Lösenord anger du ett lösenordsvärde som inte följer alla egenskaper för ett starkt lösenord som angetts.

  8. Välj knappen Fortsätt . Du ser en skärm som liknar den som visas nedan:

    skärmbild av validering av användarindata.

    Du måste korrigera dina indata innan du fortsätter.

  9. Ange rätt värden enligt felmeddelandena och välj sedan Knappen Fortsätt igen. När policyn har slutfört körningen omdirigeras du till https://jwt.ms och du ser en avkodad JWT. Token ser ut ungefär som följande JWT-kodfragment:

    {
      "typ": "JWT",
      "alg": "RS256",
      "kid": "pxLOMWFg...."
    }.{
      ...
      "sub": "c7ae4515-f7a7....",
      ...
      "acr": "b2c_1a_contosocustompolicy",
      "accountType": "work",
      ...
      "email": "maurice@contoso.com",
      "name": "Maurice Paulet",
      "message": "Hello Maurice Paulet"
    }.[Signature]

Steg 7 – Verifiera användarindata med hjälp av tekniska verifieringsprofiler

De valideringstekniker som vi har använt i steg 1, steg 2 och steg 3 gäller inte för alla scenarier. Om dina affärsregler är för komplexa för att definieras på anspråksdeklarationsnivå kan du konfigurera en teknisk validering och sedan anropa den från en Self-Asserted teknisk profil.

Anmärkning

Endast självsäkra tekniska profiler kan använda tekniska valideringsprofiler. Läs mer om teknisk valideringsprofil

Scenarioöversikt

Vi kräver att om användarens kontotyp är Contoso Employee Account måste vi se till att deras e-postdomän baseras på en uppsättning fördefinierade domäner. Dessa domäner är contoso.com, fabrikam.com och woodgrove.com. Annars visar vi ett fel för användaren tills de använder ett giltigt Contoso-anställdkonto eller byter till personligt konto.

Använd följande steg för att lära dig hur du verifierar användarindata med hjälp av tekniska verifieringsprofiler. Du använder en teknisk profil för validering av anspråkstransformeringstyp, men du kan även anropa en REST API-tjänst för att verifiera data som du lär dig senare i den här serien.

  1. I avsnittet ClaimsSchema i ContosoCustomPolicy.XML filen deklarerar du domän- och domainStatus-anspråk med hjälp av följande kod:

        <ClaimType Id="domain">
          <DataType>string</DataType>
        </ClaimType>
    
        <ClaimType Id="domainStatus">
          <DataType>string</DataType>
        </ClaimType>
    
  2. Leta upp avsnittet ClaimsTransformations och konfigurera anspråkstransformeringar med hjälp av följande kod:

        <ClaimsTransformation Id="GetDomainFromEmail" TransformationMethod="ParseDomain">
            <InputClaims>
                <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="emailAddress"/>
            </InputClaims>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="domain" TransformationClaimType="domain"/>
            </OutputClaims>
        </ClaimsTransformation>
        <ClaimsTransformation Id="LookupDomain" TransformationMethod="LookupValue">
            <InputClaims>
                <InputClaim ClaimTypeReferenceId="domain" TransformationClaimType="inputParameterId"/>
            </InputClaims>
            <InputParameters>
                <InputParameter Id="contoso.com" DataType="string" Value="valid"/>
                <InputParameter Id="fabrikam.com" DataType="string" Value="valid"/>
                <InputParameter Id="woodgrove.com" DataType="string" Value="valid"/>
                <InputParameter Id="errorOnFailedLookup" DataType="boolean" Value="true"/>
            </InputParameters>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="domainStatus" TransformationClaimType="outputClaim"/>
            </OutputClaims>
        </ClaimsTransformation>
    

    GetDomainFromEmail-anspråkstransformeringen extraherar en domän från e-post med parseDomain-metoden och lagrar den i domänanspråket. LookupDomain Claims Transformation använder den extraherade domänen för att kontrollera om den är giltig genom att leta upp den i de fördefinierade domänerna och tilldela giltig till domainStatus-anspråket.

  3. Använd följande kod för att lägga till en teknisk profil i samma anspråksleverantör som den tekniska profilen med Id=UserInformationCollector:

        <TechnicalProfile Id="CheckCompanyDomain">
            <DisplayName>Check Company validity </DisplayName>
            <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
            <InputClaimsTransformations>
                <InputClaimsTransformation ReferenceId="GetDomainFromEmail"/>
            </InputClaimsTransformations>
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="domain"/>
            </OutputClaims>
            <OutputClaimsTransformations>
                <OutputClaimsTransformation ReferenceId="LookupDomain"/>
            </OutputClaimsTransformations>
        </TechnicalProfile>
    

    Vi har deklarerat en teknisk profil för anspråksomvandling som kör anspråksomvandlingarna GetDomainFromEmail och LookupDomain.

  4. Leta upp den tekniska profilen med Id=UserInformationCollectoroch ett ValidationTechnicalProfile strax efter -elementet OutputClaims med hjälp av följande kod:

        <ValidationTechnicalProfiles>
            <ValidationTechnicalProfile ReferenceId="CheckCompanyDomain">
                <Preconditions>
                    <Precondition Type="ClaimEquals" ExecuteActionsIf="false">
                        <Value>accountType</Value>
                        <Value>work</Value>
                        <Action>SkipThisValidationTechnicalProfile</Action>
                    </Precondition>
                </Preconditions>
            </ValidationTechnicalProfile>
        </ValidationTechnicalProfiles>
    

    Vi har lagt till en teknisk valideringsprofil i den självsäkra tekniska profilen UserInformationCollector . Den tekniska profilen hoppas över endast om accountType-värdet inte är lika med work. Om den tekniska profilen körs och e-postdomänen inte är giltig utlöses ett fel.

  5. Leta upp den tekniska profilen med Id=UserInformationCollectoroch lägg till följande kod i taggen metadata .

        <Item Key="LookupNotFound">The provided email address isn't a valid Contoso Employee email.</Item>
    

    Vi har ställt in ett anpassat felmeddelande om användaren inte använder en giltig e-postadress.

  6. Följ anvisningarna i Ladda upp en anpassad principfil för att ladda upp principfilen.

  7. Följ anvisningarna i steg 6 för att testa din anpassade princip:

    1. För Kontotyp väljer du Contoso-anställdkonto
    2. För E-postadress anger du en ogiltig e-postadress, till exempel maurice@fourthcoffee.com.
    3. Ange resten av informationen efter behov och välj Fortsätt

    Eftersom maurice@fourthcoffee.com det inte är ett giltigt e-postmeddelande visas ett fel som liknar det som visas i skärmbilden nedan. Du måste använda en giltig e-postadress för att kunna köra den anpassade principen och ta emot en JWT.

    skärmbild av fel på grund av ogiltig e-postadress.