Condividi tramite


Convalidare gli input utente usando criteri personalizzati di Azure Active Directory B2C

I criteri personalizzati di Azure Active Directory B2C (Azure AD B2C) non solo consentono di rendere obbligatori gli input utente, ma anche di convalidarli. È possibile contrassegnare gli input utente come richiesto, ad esempio <DisplayClaim ClaimTypeReferenceId="givenName" Required="true"/>, ma non significa che gli utenti immettono dati validi. Azure AD B2C offre diversi modi per convalidare un input utente. In questo articolo si apprenderà come scrivere un criterio personalizzato che raccoglie gli input dell'utente e li convalida usando gli approcci seguenti:

  • Limitare i dati immessi da un utente fornendo un elenco di opzioni da scegliere. Questo approccio usa valori enumerati, che vengono aggiunti quando si dichiara un'attestazione.

  • Definire un modello che deve corrispondere a un input dell'utente. Questo approccio usa espressioni regolari, che vengono aggiunte quando si dichiara un'attestazione.

  • Definire un set di regole e richiedere che un input dell'utente rispetti una o più regole. Questo approccio usa predicati, che vengono aggiunti quando si dichiara un'attestazione.

  • Usare il tipo di attestazione speciale reenterPassword per verificare che l'utente ha immesso nuovamente la password durante la raccolta di input dell'utente.

  • Configurare un profilo tecnico di convalida che definisce regole business complesse che non possono essere definite a livello di dichiarazione di attestazione. Ad esempio, si raccoglie un input utente, che deve essere convalidato in base a un valore o a un valore impostato in un'altra attestazione.

Prerequisiti

Nota

Questo articolo fa parte della serie di procedure Creare ed eseguire criteri personalizzati in Azure Active Directory B2C. È consigliabile iniziare questa serie dal primo articolo.

Passaggio 1: Convalidare l'input dell'utente limitando le opzioni di input utente

Se si conoscono tutti i valori possibili che un utente può immettere per un determinato input, è possibile specificare un set finito di valori tra cui un utente deve selezionare. A questo scopo, è possibile usare DropdownSinglSelect, CheckboxMultiSelect e RadioSingleSelectUserInputType. In questo articolo si userà un tipo di input RadioSingleSelect :

  1. In VS Code aprire il file ContosoCustomPolicy.XML.

  2. Nell'elemento ClaimsSchema del ContosoCustomPolicy.XML file dichiarare il tipo di attestazione seguente:

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

    È stata dichiarata l'attestazione accountType . Quando il valore dell'attestazione viene raccolto dall'utente, l'utente deve selezionare l'account dipendente Contoso per un valore aziendale o un account personale per un valore personale.

    Azure AD B2C consente anche di soddisfare i criteri in lingue diverse e fornisce le restrizioni relative al tipo di account per più lingue. Per altre informazioni, vedere l'articolo Localizzare l'interfaccia utente dell'articolo Aggiungere attributi utente.

  3. Individuare il profilo tecnico con Id="UserInformationCollector", aggiungere l'attestazione accountType come attestazione di visualizzazione usando il codice seguente:

        <DisplayClaim ClaimTypeReferenceId="accountType" Required="true"/>
    
  4. Nel profilo tecnico con Id="UserInformationCollector"aggiungere l'attestazione accountType come attestazione di output usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="accountType"/>
    
  5. Per includere l'attestazione del tipo di account nel token di accesso, individuare l'elemento , aggiungere l'attestazione RelyingParty accountType come attestazione di token usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="accountType" />
    

Passaggio 2: Convalidare l'input dell'utente usando espressioni regolari

Quando non è possibile conoscere in anticipo tutti i possibili valori di input utente, è possibile consentire all'utente di immettere i dati stessi. In questo caso, è possibile usare espressioni regolari (regex) o criteri per determinare come deve essere formattato un input utente. Ad esempio, un messaggio di posta elettronica deve avere il simbolo (@) e un punto (.) da qualche parte nel testo.

Quando si dichiara un'attestazione, i criteri personalizzati consentono di definire un'espressione regolare, che l'input dell'utente deve corrispondere. Facoltativamente, è possibile fornire un messaggio visualizzato all'utente, se l'input non corrisponde all'espressione.

  1. Individuare l'elemento e dichiarare l'attestazione ClaimsSchema di posta elettronica usando il codice seguente:

        <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. Individuare il profilo tecnico con Id="UserInformationCollector", aggiungere l'attestazione di posta elettronica come attestazione di visualizzazione usando il codice seguente:

        <DisplayClaim ClaimTypeReferenceId="email" Required="true"/>
    
  3. Nel profilo tecnico con Id="UserInformationCollector"aggiungere l'attestazione di posta elettronica come attestazione di output usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="email"/>
    
  4. Individuare l'elemento RelyingParty , aggiungere il messaggio di posta elettronica come attestazione di token usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="email" />
    

Passaggio 3: Convalidare l'input dell'utente usando predicati

È stata usata l'espressione regolare per convalidare gli input utente. Tuttavia, l'espressione regolare presenta una debolezza, ovvero il messaggio di errore viene visualizzato fino a quando non si corregge l'input senza mostrare il requisito specifico mancante.

Le convalide dei predicati consentono di risolvere questo problema consentendo di definire un set di regole (predicati) e un messaggio di errore indipendente per ogni regola. Nei criteri personalizzati, un predicato ha un metodo predefinito, che definisce i controlli che si desidera eseguire. Ad esempio, è possibile usare il metodo di predicato IsLengthRange per verificare se una password utente è compresa nell'intervallo di parametri minimo e massimo (valori) specificati.

Mentre i predicati definiscono la convalida per verificare in base a un tipo di attestazione, PredicateValidations raggruppa un set di predicati per formare una convalida di input utente che può essere applicata a un tipo di attestazione. Ad esempio, si crea un gruppo di predicati di convalida che convalida diversi tipi di caratteri consentiti per una password. Gli elementi Predicates e PredicateValidations sono elementi figlio della BuildingBlocks sezione del file di criteri.

  1. Individuare l'elemento e dichiarare l'attestazione ClaimsSchema della password usando il codice seguente:

        <ClaimType Id="password">
          <DisplayName>Password</DisplayName>
          <DataType>string</DataType>
          <AdminHelpText>Enter password</AdminHelpText>
          <UserHelpText>Enter password</UserHelpText>
          <UserInputType>Password</UserInputType>
        </ClaimType>
    
  2. Aggiungere un Predicates elemento come elemento figlio della BuildingBlocks sezione usando il codice seguente. Aggiungere l'elemento Predicates sotto l'elemento ClaimsSchema :

        <Predicates>
    
        </Predicates>
    
  3. All'interno dell'elemento Predicates definire i predicati usando il codice seguente:

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

    Sono state definite diverse regole, che, quando vengono raggruppate, descrivono una password accettabile. Successivamente, è possibile raggruppare i predicati per formare un set di criteri password che è possibile usare nei criteri.

  4. Aggiungere un PredicateValidations elemento come elemento figlio della BuildingBlocks sezione usando il codice seguente. Aggiungere l'elemento PredicateValidations come elemento figlio della BuildingBlocks sezione, ma sotto l'elemento Predicates :

        <PredicateValidations>
    
        </PredicateValidations>
    
  5. All'interno dell'elemento PredicateValidations definire PredicateValidations usando il codice seguente:

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

    Sono stati definiti tre predicati di convalida, StrongPassword, CustomPassword e SimplePassword. A seconda delle caratteristiche della password che si vuole che gli utenti inserisca, è possibile usare qualsiasi elemento nelle convalide del predicato. In questo articolo si userà una password complessa.

  6. Individuare la dichiarazione tipo di attestazione password e aggiungere la convalida del predicato StrongPassword subito dopo la dichiarazione dell'elemento UserInputType che contiene usando il codice seguente:

        <PredicateValidationReference Id="StrongPassword" />
    
  7. Individuare il profilo tecnico con Id="UserInformationCollector", aggiungere l'attestazione password come attestazione di visualizzazione usando il codice seguente:

        <DisplayClaim ClaimTypeReferenceId="password" Required="true"/>
    
  8. Nel profilo tecnico con Id="UserInformationCollector"aggiungere l'attestazione password come attestazione di output usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="password"/>
    

Nota

Per motivi di sicurezza, non aggiungeremo la password di un utente come attestazione nel token generato dai criteri. Non aggiungiamo quindi l'attestazione password all'elemento relying party.

Passaggio 4- Convalidare la password e confermare la password

È possibile richiedere agli utenti di immettere la password due volte come mezzo per confermare che l'utente memorizza la password che inserisce. In questo caso, è necessario verificare che i valori delle due voci corrispondano. I criteri personalizzati offrono un modo semplice per raggiungere questo requisito. I tipi di attestazione password e reenterPassword sono considerati speciali, quindi quando vengono usati per raccogliere gli input utente, l'interfaccia utente convalida che l'utente ha immesso nuovamente la password.

Usare la procedura seguente per convalidare la reimpostazione della password nei criteri personalizzati:

  1. ClaimsSchema Nella sezione del ContosoCustomPolicy.XML file dichiarare l'attestazione reenterPassword subito dopo l'attestazione password usando il codice seguente:

        <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. Per raccogliere l'input di conferma della password dall'utente, individuare il UserInformationCollector profilo tecnico autocertiviato, aggiungere l'attestazione reenterPassword come attestazione di visualizzazione usando il codice seguente:

        <DisplayClaim ClaimTypeReferenceId="reenterPassword" Required="true"/>
    
  3. ContosoCustomPolicy.XML Nel file individuare il UserInformationCollector profilo tecnico autocertiviato, aggiungere l'attestazione reenterPassword come attestazione di output usando il codice seguente:

        <OutputClaim ClaimTypeReferenceId="reenterPassword"/>
    

Passaggio 5 - Caricare un file di criteri personalizzato

A questo punto, sono stati creati i criteri per affrontare i primi tre approcci alla convalida dell'input dell'utente.

Seguire la procedura descritta in Caricare un file di criteri personalizzato. Se si carica un file con lo stesso nome di quello già presente nel portale, assicurarsi di selezionare Sovrascrivi il criterio personalizzato, se già esistente.

Passaggio 6 - Testare i criteri personalizzati

  1. In Criteri personalizzati selezionare B2C_1A_CONTOSOCUSTOMPOLICY.

  2. Per Selezionare l'applicazione nella pagina di panoramica dei criteri personalizzati, selezionare l'applicazione Web, ad esempio webapp1 registrata in precedenza. Assicurarsi che il valore Select reply URL (Seleziona URL di risposta) sia impostato suhttps://jwt.ms .

  3. Selezionare Il pulsante Esegui adesso .

  4. Immettere Il nome e il cognome specificati.

  5. Selezionare Tipo di account.

  6. Per Indirizzo di posta elettronica immettere un valore di posta elettronica non formattato correttamente, ad esempio maurice@contoso.

  7. Per Password immettere il valore della password che non rispetta tutte le caratteristiche di una password complessa impostata.

  8. Selezionare il pulsante Continua . Verrà visualizzata una schermata simile a quella illustrata di seguito:

    screenshot of validating user inputs.

    Prima di continuare, è necessario correggere gli input.

  9. Immettere i valori corretti suggeriti dai messaggi di errore e quindi selezionare di nuovo il pulsante Continua . Al termine dell'esecuzione del criterio, si viene reindirizzati a https://jwt.mse viene visualizzato un token JWT decodificato. Il token è simile al frammento di token JWT seguente:

    {
      "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]

Passaggio 7: Convalidare l'input dell'utente usando i profili tecnici di convalida

Le tecniche di convalida usate nel passaggio 1, il passaggio 2 e il passaggio 3 non sono applicabili a tutti gli scenari. Se le regole business sono complesse da definire a livello di dichiarazione di attestazione, è possibile configurare una convalida tecnica e quindi chiamarla da un profilo tecnico autocertivo.

Nota

Solo i profili tecnici autocertificati possono usare profili tecnici di convalida. Altre informazioni sul profilo tecnico di convalida

Panoramica dello scenario

È necessario che, se il tipo di account dell'utente è Account dipendente Contoso, è necessario assicurarsi che il dominio di posta elettronica sia basato su un set di domini predefiniti. Questi domini sono contoso.com, fabrikam.com e woodgrove.com. In caso contrario, viene visualizzato un errore per l'utente finché non usa un account dipendente Contoso valido o si passa all'account personale.

Usare la procedura seguente per informazioni su come convalidare l'input dell'utente usando profili tecnici di convalida. Si usa un profilo tecnico di convalida dei tipi di trasformazione delle attestazioni, ma è anche possibile chiamare un servizio API REST per convalidare i dati man mano che si apprenderà più avanti in questa serie.

  1. ClaimsSchema Nella sezione del ContosoCustomPolicy.XML file dichiarare le attestazioni domain e domainStatus usando il codice seguente:

        <ClaimType Id="domain">
          <DataType>string</DataType>
        </ClaimType>
    
        <ClaimType Id="domainStatus">
          <DataType>string</DataType>
        </ClaimType>
    
  2. Individuare la ClaimsTransformations sezione e configurare le trasformazioni delle attestazioni usando il codice seguente:

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

    La trasformazione delle attestazioni GetDomainFromEmail estrae un dominio dal messaggio di posta elettronica usando il metodo ParseDomain e lo archivia nell'attestazione di dominio . La trasformazione Attestazioni LookupDomain usa il dominio estratto per verificare se è valido cercandolo nei domini predefiniti e assegnando validità all'attestazione domainStatus.

  3. Usare il codice seguente per aggiungere un profilo tecnico nello stesso provider di attestazioni del profilo tecnico con 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>
    

    È stato dichiarato il profilo tecnico della trasformazione delle attestazioni, che esegue le trasformazioni delle attestazioni GetDomainFromEmail e LookupDomain .

  4. Individuare il profilo tecnico con Id=UserInformationCollectore un subito ValidationTechnicalProfile dopo l'elemento OutputClaims usando il codice seguente:

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

    È stato aggiunto un profilo tecnico di convalida al profilo tecnico Autocertificato UserInformationCollector . Il profilo tecnico viene ignorato solo se il valore accountType non è uguale al lavoro. Se il profilo tecnico viene eseguito e il dominio di posta elettronica non è valido, viene generato un errore.

  5. Individuare il profilo tecnico con Id=UserInformationCollectore aggiungere il codice seguente all'interno del metadata tag .

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

    È stato configurato un errore personalizzato nel caso in cui l'utente non usi un messaggio di posta elettronica valido.

  6. Seguire le istruzioni in Caricare un file di criteri personalizzato per caricare il file dei criteri.

  7. Seguire le istruzioni nel passaggio 6 per testare i criteri personalizzati:

    1. Per Tipo di account selezionare Account dipendente Contoso
    2. Per Indirizzo di posta elettronica immettere un indirizzo di posta elettronica non valido, maurice@fourthcoffee.comad esempio .
    3. Immettere il resto dei dettagli in base alle esigenze e selezionare Continua

    Poiché maurice@fourthcoffee.com non è un messaggio di posta elettronica valido, verrà visualizzato un errore simile a quello illustrato nello screenshot seguente. È necessario usare un indirizzo di posta elettronica valido per eseguire correttamente i criteri personalizzati e ricevere un token JWT.

    screenshot of error due to invalid email address.

Passaggi successivi