Compartilhar via


Verificação de email personalizada com o SendGrid

Antes de começar, use o seletor Escolher um tipo de política para escolher o tipo de política que você está configurando. O Azure Active Directory B2C oferece dois métodos para definir como os usuários interagem com seus aplicativos: por meio de fluxos dos usuários predefinidos ou de políticas personalizadas totalmente configuráveis. As etapas necessárias neste artigo são diferentes para cada método.

Use o email personalizado no Azure AD B2C (Azure Active Directory B2C) para enviar email personalizado aos usuários que se inscrevem para usar seus aplicativos. Com o provedor de email terceirizado SendGrid, você pode usar um modelo de email, um endereço de Remetente: e um assunto próprios, bem como dar suporte às configurações de localização e senha de uso único (OTP) personalizada.

Esse recurso só está disponível para políticas personalizadas. Para obter as etapas de instalação, escolha Política personalizada no seletor anterior.

A verificação de email personalizada requer o uso de um provedor de email terceirizado, como o SendGrid, o Mailjet ou o SparkPost, uma API REST personalizada ou qualquer provedor de email baseado em HTTP (incluindo seu próprio). Este artigo descreve como configurar uma solução que usa o SendGrid.

Criar uma conta do SendGrid

Se você ainda não tem um, comece configurando uma conta no SendGrid. Para obter instruções de instalação, consulte a seção Criar uma conta do SendGrid em Como enviar um email usando o SendGrid com o Azure.

Certifique-se de concluir a seção na qual você cria uma chave de API SendGrid. Registre a chave de API para uso em uma etapa posterior.

Importante

O SendGrid oferece aos clientes a capacidade de enviar emails de endereços IP dedicados e compartilhados. Ao usar endereços IP dedicados, é necessário criar a própria reputação corretamente com um aquecimento de endereço IP. Para obter mais informações, consulte Aquecimento de um endereço IP.

Criar chave de política do Azure AD B2C

Em seguida, armazene a chave de API do SendGrid em uma chave de política do Azure AD B2C que será referenciada por suas políticas.

  1. Entre no portal do Azure.
  2. Se você tiver acesso a vários locatários, selecione o ícone Configurações no menu superior para alternar para o seu locatário do Azure Active Directory B2C no menu Diretórios + assinaturas.
  3. No canto superior esquerdo do portal do Azure, escolha Todos os serviçose pesquise e selecione Azure AD B2C.
  4. Na página de Visão Geral, selecione Estrutura de Experiência de Identidade.
  5. Selecione Chaves de Política e, em seguida, escolha Adicionar.
  6. Para Opções, escolha Manual.
  7. Insira um Nome para a chave de política. Por exemplo, SendGridSecret. O prefixo B2C_1A_ será adicionado automaticamente ao nome da chave.
  8. Em Segredo, insira a chave de API do SendGrid registrada anteriormente.
  9. Para Uso de chave, selecione Assinatura.
  10. Selecione Criar.

Criar modelo do SendGrid

Com uma conta do SendGrid criada e a chave de API do SendGrid armazenada em uma chave de política do Azure AD B2C, crie um modelo transacional dinâmico.

  1. No site do SendGrid, abra a página de modelos transacionais e selecione Criar um modelo dinâmico.

  2. Insira um nome de modelo exclusivo como Verification email e selecione Criar.

  3. Para começar a editar seu novo modelo, selecione o modelo, ou seja, Verification email, e, em seguida, selecione Adicionar versão.

  4. Selecione Modelo em branco e, em seguida, Editor de código.

  5. No editor de HTML, cole o modelo HTML a seguir ou use um próprio. Os parâmetros {{otp}} e {{email}} são substituídos dinamicamente pelo valor de senha única e pelo endereço de email do usuário.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en"><head id="Head1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Contoso demo account email verification code</title><meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
       <style>
           table td {border-collapse:collapse;margin:0;padding:0;}
       </style>
    </head>
    <body dir="ltr" lang="en">
       <table width="100%" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en">
            <tr>
               <td valign="top" width="50%"></td>
               <td valign="top">
                  <!-- Email Header -->
                  <table width="640" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en" style="border-left:1px solid #e3e3e3;border-right: 1px solid #e3e3e3;">
                   <tr style="background-color: #0072C6;">
                       <td width="1" style="background:#0072C6; border-top:1px solid #e3e3e3;"></td>
                       <td width="24" style="border-top:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td width="310" valign="middle" style="border-top:1px solid #e3e3e3; border-bottom:1px solid #e3e3e3;padding:12px 0;">
                           <h1 style="line-height:20pt;font-family:Segoe UI Light; font-size:18pt; color:#ffffff; font-weight:normal;">
                            <span id="HeaderPlaceholder_UserVerificationEmailHeader"><font color="#FFFFFF">Verify your email address</font></span>
                           </h1>
                       </td>
                       <td width="24" style="border-top: 1px solid #e3e3e3;border-bottom: 1px solid #e3e3e3;">&nbsp;</td>
                   </tr>
                  </table>
                  <!-- Email Content -->
                  <table width="640" cellpadding="0" cellspacing="0" border="0" dir="ltr" lang="en">
                   <tr>
                       <td width="1" style="background:#e3e3e3;"></td>
                       <td width="24">&nbsp;</td>
                       <td id="PageBody" width="640" valign="top" colspan="2" style="border-bottom:1px solid #e3e3e3;padding:10px 0 20px;border-bottom-style:hidden;">
                           <table cellpadding="0" cellspacing="0" border="0">
                               <tr>
                                   <td width="630" style="font-size:10pt; line-height:13pt; color:#000;">
                                       <table cellpadding="0" cellspacing="0" border="0" width="100%" style="" dir="ltr" lang="en">
                                           <tr>
                                               <td>
    
       <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333;">
           <span id="BodyPlaceholder_UserVerificationEmailBodySentence1">Thanks for verifying your {{email}} account!</span>
       </div>
       <br>
       <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333; font-weight: bold">
           <span id="BodyPlaceholder_UserVerificationEmailBodySentence2">Your code is: {{otp}}</span>
       </div>
       <br>
       <br>
    
                                                   <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; color:#333;">
                                                   Sincerely,
                                                   </div>
                                                   <div style="font-family:'Segoe UI', Tahoma, sans-serif; font-size:14px; font-style:italic; color:#333;">
                                                       Contoso
                                                   </div>
                                               </td>
                                           </tr>
                                       </table>
                                   </td>
                               </tr>
                           </table>
    
                       </td>
    
                       <td width="1">&nbsp;</td>
                       <td width="1"></td>
                       <td width="1">&nbsp;</td>
                       <td width="1" valign="top"></td>
                       <td width="29">&nbsp;</td>
                       <td width="1" style="background:#e3e3e3;"></td>
                   </tr>
                   <tr>
                       <td width="1" style="background:#e3e3e3; border-bottom:1px solid #e3e3e3;"></td>
                       <td width="24" style="border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td id="PageFooterContainer" width="585" valign="top" colspan="6" style="border-bottom:1px solid #e3e3e3;padding:0px;">
    
                       </td>
    
                       <td width="29" style="border-bottom:1px solid #e3e3e3;">&nbsp;</td>
                       <td width="1" style="background:#e3e3e3; border-bottom:1px solid #e3e3e3;"></td>
                   </tr>
                  </table>
    
               </td>
               <td valign="top" width="50%"></td>
           </tr>
       </table>
    </body>
    </html>
    
  6. Expanda o menu Configurações e, para o Nome da versão, insira uma versão de modelo.

  7. Para Assunto, insira {{subject}}.

  8. Selecione Salvar.

  9. Retorne à página Modelos transacionais selecionando a seta para voltar.

  10. Registre a ID do modelo que você criou para uso em uma etapa posterior. Por exemplo, d-989077fbba9746e89f3f6411f596fb96. Especifique essa ID ao adicionar a transformação de declarações.

Importante

As próximas etapas mostram como criar os arquivos XML de política personalizada. Recomendamos usar uma política personalizada de verificação de email personalizada de exemplo que está disponível no GitHub. DisplayControl_TrustFrameworkExtensions.xmlusa TrustFrameworkExtensions.xml como arquivo base, portanto, certifique-se de incluir os arquivos TrustFrameworkBase.xml, TrustFrameworkLocalization.xml e TrustFrameworkExtensions.xml do pacote de inícioSocialAndLocalAccounts em sua política.

Adicionar tipos de declaração do Azure AD B2C

Na sua política, adicione os tipos de declaração a seguir ao elemento <ClaimsSchema> em <BuildingBlocks>.

Esses tipos de declarações são necessários para gerar e verificar o endereço de email usando um código de OTP (senha de uso único).

<!-- 
<BuildingBlocks>
  <ClaimsSchema> -->
    <ClaimType Id="Otp">
      <DisplayName>Secondary One-time password</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="emailRequestBody">
      <DisplayName>SendGrid request body</DisplayName>
      <DataType>string</DataType>
    </ClaimType>
    <ClaimType Id="VerificationCode">
      <DisplayName>Secondary Verification Code</DisplayName>
      <DataType>string</DataType>
      <UserHelpText>Enter your email verification code</UserHelpText>
      <UserInputType>TextBox</UserInputType>
    </ClaimType>
  <!-- 
  </ClaimsSchema>
</BuildingBlocks> -->

Adicionar transformações de declarações

Em seguida, você precisa de uma transformação de declarações para gerar uma declaração de cadeia de caracteres JSON que forma o corpo da solicitação enviada ao SendGrid.

A estrutura do objeto JSON é definida pelas IDs na notação de ponto de InputParameters e TransformationClaimTypes do InputClaims. Os números na notação de ponto implicam matrizes. Os valores são provenientes dos valores de InputClaims e das propriedades de "valor" de InputParameters. Para obter mais informações sobre transformações de declarações JSON, confira Transformações de declarações JSON.

Adicione a transformação de declarações a seguir ao elemento <ClaimsTransformations> em <BuildingBlocks>. Faça as seguintes atualizações para o XML de transformação de declarações:

  • Atualize o valor InputParameter de template_id com a ID do modelo transacional do SendGrid criado anteriormente em Criar um modelo do SendGrid.
  • Atualize o valor do endereço from.email. Use um endereço de email válido para ajudar a impedir que o email de verificação seja marcado como spam.

    Observação

    É necessário verificar esse endereço de email no SendGrid em Autenticação de Remetente com autenticação de domínio ou Autenticação de Remetente Único.

  • Atualize o valor do parâmetro de entrada da linha do assunto personalizations.0.dynamic_template_data.subject com uma linha de assunto apropriada para sua organização.
<!-- 
<BuildingBlocks>
  <ClaimsTransformations> -->
    <ClaimsTransformation Id="GenerateEmailRequestBody" TransformationMethod="GenerateJson">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.to.0.email" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="personalizations.0.dynamic_template_data.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.dynamic_template_data.email" />
      </InputClaims>
      <InputParameters>
        <!-- Update the template_id value with the ID of your SendGrid template. -->
        <InputParameter Id="template_id" DataType="string" Value="d-989077fbba9746e89f3f6411f596fb96"/>
        <InputParameter Id="from.email" DataType="string" Value="my_email@mydomain.com"/>
        <!-- Update with a subject line appropriate for your organization. -->
        <InputParameter Id="personalizations.0.dynamic_template_data.subject" DataType="string" Value="Contoso account email verification code"/>
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim"/>
      </OutputClaims>
    </ClaimsTransformation>
  <!--
  </ClaimsTransformations>
</BuildingBlocks> -->

Adicionar definição de conteúdo DataUri

Abaixo das transformações de declarações em <BuildingBlocks>, adicione o seguinte ContentDefinition para fazer referência ao URI de dados da versão 2.1.2:

<!--
<BuildingBlocks> -->
  <ContentDefinitions>
   <ContentDefinition Id="api.localaccountsignup">
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
    </ContentDefinition>
    <ContentDefinition Id="api.localaccountpasswordreset">
      <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
    </ContentDefinition>
  </ContentDefinitions>
<!--
</BuildingBlocks> -->

Criar um DisplayControl

Um controle de exibição de verificação é usado para verificar o endereço de email com um código de verificação que o usuário recebe.

Este exemplo de controle de exibição está configurado para:

  1. Coletar o tipo de declaração de endereço email do usuário.

  2. Usando a ação SendCode, gerar um código de OTP e enviar um email com o código de OTP para o usuário.

    Send verification code email action

  3. Aguardar até que o usuário forneça o tipo de declaração verificationCode com o código enviado ao usuário.

  4. Retorne o email para o perfil técnico autodeclarado que tem uma referência a esse controle de exibição.

Em definições de conteúdo, ainda em <BuildingBlocks>, adicione o DisplayControl do tipo VerificationControl a seguir à sua política.

<!--
<BuildingBlocks> -->
  <DisplayControls>
    <DisplayControl Id="emailVerificationControl" UserInterfaceControlType="VerificationControl">
      <DisplayClaims>
        <DisplayClaim ClaimTypeReferenceId="email" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="verificationCode" ControlClaimType="VerificationCode" Required="true" />
      </DisplayClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="email" />
      </OutputClaims>
      <Actions>
        <Action Id="SendCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="GenerateOtp" />
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="SendOtp" />
          </ValidationClaimsExchange>
        </Action>
        <Action Id="VerifyCode">
          <ValidationClaimsExchange>
            <ValidationClaimsExchangeTechnicalProfile TechnicalProfileReferenceId="VerifyOtp" />
          </ValidationClaimsExchange>
        </Action>
      </Actions>
    </DisplayControl>
  </DisplayControls>
<!--
</BuildingBlocks> -->

Adicionar perfis técnicos de OTP

O perfil técnico GenerateOtp gera um código para o endereço de email. O perfil técnico VerifyOtp verifica o código associado ao endereço de email. Você pode alterar a configuração do formato e a expiração da senha de uso único. Para obter mais informações sobre perfis técnicos de OTP, confira Definir um perfil técnico de senha de uso único.

Observação

Códigos OTP gerados pelo protocolo Web.TPEngine.Providers.OneTimePasswordProtocolProvider estão vinculados à sessão do navegador. Isso significa que um usuário pode gerar códigos OTP exclusivos em sessões de navegador diferentes que são válidas para suas sessões correspondentes. Por outro lado, um código OTP gerado pelo provedor de email interno é independente da sessão do navegador, portanto, se um usuário gerar um novo código OTP em uma nova sessão do navegador, ele substituirá o código OTP anterior.

Adicione os perfis técnicos a seguir ao elemento <ClaimsProviders>.

<!--
<ClaimsProviders> -->
  <ClaimsProvider>
    <DisplayName>One time password technical profiles</DisplayName>
    <TechnicalProfiles>
      <TechnicalProfile Id="GenerateOtp">
        <DisplayName>Generate one time password</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.OneTimePasswordProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="Operation">GenerateCode</Item>
          <Item Key="CodeExpirationInSeconds">600</Item>
          <Item Key="CodeLength">6</Item>
          <Item Key="CharacterSet">0-9</Item>
          <Item Key="NumRetryAttempts">5</Item>
          <Item Key="NumCodeGenerationAttempts">10</Item>
          <Item Key="ReuseSameCode">false</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="identifier" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="otp" PartnerClaimType="otpGenerated" />
        </OutputClaims>
      </TechnicalProfile>

      <TechnicalProfile Id="VerifyOtp">
        <DisplayName>Verify one time password</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.OneTimePasswordProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="Operation">VerifyCode</Item>
        </Metadata>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="email" PartnerClaimType="identifier" />
          <InputClaim ClaimTypeReferenceId="verificationCode" PartnerClaimType="otpToVerify" />
        </InputClaims>
      </TechnicalProfile>
     </TechnicalProfiles>
  </ClaimsProvider>
<!--
</ClaimsProviders> -->

Adicionar um perfil técnico da API REST

Esse perfil técnico da API REST gera o conteúdo do email (usando o formato do SendGrid). Para obter mais informações sobre perfis técnicos RESTful, confira Definir um perfil técnico RESTful.

Assim como acontece com os perfis técnicos de OTP, adicione os perfis técnicos a seguir ao elemento <ClaimsProviders>.

<ClaimsProvider>
  <DisplayName>RestfulProvider</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="SendOtp">
      <DisplayName>Use SendGrid's email API to send the code to the user</DisplayName>
      <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <Metadata>
        <Item Key="ServiceUrl">https://api.sendgrid.com/v3/mail/send</Item>
        <Item Key="AuthenticationType">Bearer</Item>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="ClaimUsedForRequestPayload">emailRequestBody</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_SendGridSecret" />
      </CryptographicKeys>
      <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateEmailRequestBody" />
      </InputClaimsTransformations>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="emailRequestBody" />
      </InputClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

Fazer uma referência ao DisplayControl

Na etapa final, adicione uma referência ao DisplayControl que você criou. Substitua os perfis técnicos existentes e autodeclarados LocalAccountSignUpWithLogonEmail e LocalAccountDiscoveryUsingEmailAddress que estão configurados na política de base pelo snippet de código XML a seguir. Se você tiver usado uma versão anterior da política do Azure AD B2C, esses perfis técnicos usarão DisplayClaims com uma referência a DisplayControl.

Para obter mais informações, confira Perfil técnico autodeclarado e DisplayControl.

<ClaimsProvider>
  <DisplayName>Local Account</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="LocalAccountSignUpWithLogonEmail">
      <DisplayClaims>
        <DisplayClaim DisplayControlReferenceId="emailVerificationControl" />
        <DisplayClaim ClaimTypeReferenceId="displayName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="givenName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="surName" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="newPassword" Required="true" />
        <DisplayClaim ClaimTypeReferenceId="reenterPassword" Required="true" />
      </DisplayClaims>
    </TechnicalProfile>
    <TechnicalProfile Id="LocalAccountDiscoveryUsingEmailAddress">
      <DisplayClaims>
        <DisplayClaim DisplayControlReferenceId="emailVerificationControl" />
      </DisplayClaims>
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

[Opcional] Localizar seu email

Para localizar o email, envie cadeias de caracteres localizadas ao SendGrid ou ao seu provedor de email. Por exemplo, você pode localizar o assunto do email, o corpo, a mensagem de código ou a assinatura do email. Para fazer isso, use a transformação de declarações GetLocalizedStringsTransformation para copiar cadeias de caracteres localizadas em tipos de declaração. A transformação de declarações GenerateEmailRequestBody, que gera o conteúdo JSON, usa declarações de entrada que contêm as cadeias de caracteres localizadas.

  1. Na sua política, defina as seguintes declarações de cadeia de caracteres: assunto, mensagem, codeIntro e assinatura.

  2. Defina uma transformação de declarações GetLocalizedStringsTransformation para substituir os valores de cadeia de caracteres localizados nas declarações da etapa 1.

  3. Altere a transformação de declarações GenerateEmailRequestBody para usar declarações de entrada com o snippet de código XML a seguir.

  4. Atualize seu modelo SendGrid para usar parâmetros dinâmicos no lugar de todas as cadeias de caracteres localizadas pelo Azure AD B2C.

    <ClaimsTransformation Id="GetLocalizedStringsForEmail" TransformationMethod="GetLocalizedStringsTransformation">
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="subject" TransformationClaimType="email_subject" />
        <OutputClaim ClaimTypeReferenceId="message" TransformationClaimType="email_message" />
        <OutputClaim ClaimTypeReferenceId="codeIntro" TransformationClaimType="email_code" />
        <OutputClaim ClaimTypeReferenceId="signature" TransformationClaimType="email_signature" />
      </OutputClaims>
    </ClaimsTransformation>
    <ClaimsTransformation Id="GenerateEmailRequestBody" TransformationMethod="GenerateJson">
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.to.0.email" />
        <InputClaim ClaimTypeReferenceId="subject" TransformationClaimType="personalizations.0.dynamic_template_data.subject" />
        <InputClaim ClaimTypeReferenceId="otp" TransformationClaimType="personalizations.0.dynamic_template_data.otp" />
        <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.dynamic_template_data.email" />
        <InputClaim ClaimTypeReferenceId="message" TransformationClaimType="personalizations.0.dynamic_template_data.message" />
        <InputClaim ClaimTypeReferenceId="codeIntro" TransformationClaimType="personalizations.0.dynamic_template_data.codeIntro" />
        <InputClaim ClaimTypeReferenceId="signature" TransformationClaimType="personalizations.0.dynamic_template_data.signature" />
      </InputClaims>
      <InputParameters>
        <InputParameter Id="template_id" DataType="string" Value="d-1234567890" />
        <InputParameter Id="from.email" DataType="string" Value="my_email@mydomain.com" />
      </InputParameters>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="emailRequestBody" TransformationClaimType="outputClaim" />
      </OutputClaims>
    </ClaimsTransformation>
    
  5. Adicione o elemento Localization a seguir.

    <!--
    <BuildingBlocks> -->
      <Localization Enabled="true">
        <SupportedLanguages DefaultLanguage="en" MergeBehavior="ReplaceAll">
          <SupportedLanguage>en</SupportedLanguage>
          <SupportedLanguage>es</SupportedLanguage>
        </SupportedLanguages>
        <LocalizedResources Id="api.custom-email.en">
          <LocalizedStrings>
            <!--Email template parameters-->
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_subject">Contoso account email verification code</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_message">Thanks for validating the account</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_code">Your code is</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_signature">Sincerely</LocalizedString>
          </LocalizedStrings>
        </LocalizedResources>
        <LocalizedResources Id="api.custom-email.es">
          <LocalizedStrings>
            <!--Email template parameters-->
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_subject">Código de verificación del correo electrónico de la cuenta de Contoso</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_message">Gracias por comprobar la cuenta de </LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_code">Su código es</LocalizedString>
            <LocalizedString ElementType="GetLocalizedStringsTransformationClaimType" StringId="email_signature">Sinceramente</LocalizedString>
          </LocalizedStrings>
        </LocalizedResources>
      </Localization>
    <!--
    </BuildingBlocks> -->
    
  6. Adicione referências aos elementos LocalizedResources atualizando o elemento ContentDefinitions.

    <!--
    <BuildingBlocks> -->
      <ContentDefinitions>
        <ContentDefinition Id="api.localaccountsignup">
          <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
          <LocalizedResourcesReferences MergeBehavior="Prepend">
            <LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.custom-email.en" />
            <LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="api.custom-email.es" />
          </LocalizedResourcesReferences>
        </ContentDefinition>
        <ContentDefinition Id="api.localaccountpasswordreset">
          <DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:2.1.2</DataUri>
          <LocalizedResourcesReferences MergeBehavior="Prepend">
            <LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="api.custom-email.en" />
            <LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="api.custom-email.es" />
          </LocalizedResourcesReferences>
        </ContentDefinition>
      </ContentDefinitions>
    <!--
    </BuildingBlocks> -->
    
  7. Por fim, adicione a transformação de declarações de entrada a seguir aos perfis técnicos LocalAccountSignUpWithLogonEmail e LocalAccountDiscoveryUsingEmailAddress.

    <InputClaimsTransformations>
      <InputClaimsTransformation ReferenceId="GetLocalizedStringsForEmail" />
    </InputClaimsTransformations>
    

[Opcional] Localizar a interface do usuário

O elemento Localization permite que você dê suporte a várias localidades ou idiomas na política para os percursos do usuário. O suporte à localização em políticas permite que você forneça cadeias de caracteres específicas a um idioma para os Elementos da interface do usuário do controle de exibição de verificação e as Mensagens de erro de senha de uso único. Adicionar o LocalizedString a seguir a LocalizedResources.

<LocalizedResources Id="api.custom-email.en">
  <LocalizedStrings>
    ...
    <!-- Display control UI elements-->
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="intro_msg">Verification is necessary. Please click Send button.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="success_send_code_msg">Verification code has been sent to your inbox. Please copy it to the input box below.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="failure_send_code_msg">We are having trouble verifying your email address. Please enter a valid email address and try again.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="success_verify_code_msg">E-mail address verified. You can now continue.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="failure_verify_code_msg">We are having trouble verifying your email address. Please try again.</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_send_code">Send verification code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_verify_code">Verify code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_send_new_code">Send new code</LocalizedString>
    <LocalizedString ElementType="DisplayControl" ElementId="emailVerificationControl" StringId="but_change_claims">Change e-mail</LocalizedString>
    <!-- Claims-->
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="DisplayName">Verification Code</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="UserHelpText">Verification code received in the email.</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="emailVerificationCode" StringId="AdminHelpText">Verification code received in the email.</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="email" StringId="DisplayName">Email</LocalizedString>
    <!-- Email validation error messages-->
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfSessionDoesNotExist">You have exceeded the maximum time allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfMaxRetryAttempted">You have exceeded the number of retries allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfMaxNumberOfCodeGenerated">You have exceeded the number of code generation attempts allowed.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfInvalidCode">You have entered the wrong code.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfSessionConflict">Cannot verify the code, please try again later.</LocalizedString>
    <LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfVerificationFailedRetryAllowed">The verification has failed, please try again.</LocalizedString>
  </LocalizedStrings>
</LocalizedResources>

Próximas etapas