Compartilhar via


Verificação de email personalizada com SendGrid

Importante

A partir de 1º de maio de 2025, o Azure AD B2C não estará mais disponível para compra para novos clientes. Saiba mais em nossas perguntas frequentes.

Antes de começar, use o seletor Escolher um tipo de política na parte superior desta página 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 emails personalizados no Azure Active Directory B2C (Azure AD B2C) para enviar mensagens personalizadas aos usuários que se inscreverem para usar seus aplicativos. Usando o provedor de email de terceiros SendGrid, você pode usar seu próprio modelo de email e de: endereço e assunto, bem como dar suporte à localização e configurações personalizadas de senha única (OTP).

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

A verificação personalizada de email requer o uso de um provedor de email de terceiros, como SendGrid, Mailjet ou SparkPost, uma API REST personalizada ou qualquer provedor de email baseado em HTTP (incluindo o seu). 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.

Conclua 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 IP compartilhados e endereços IP dedicados. 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 da API SendGrid em uma chave de política do Azure AD B2C para que suas políticas façam referência.

  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ços e pesquise e selecione o Azure AD B2C.
  4. Na página Visão geral, selecione Identity Experience Framework.
  5. Selecione Chaves de Política e, em seguida, selecione Adicionar.
  6. Para Opções, escolha Manual.
  7. Insira um Nome para a chave de política. Por exemplo, SendGridSecret. O prefixo B2C_1A_ é adicionado automaticamente ao nome da chave.
  8. Em Segredo, insira a chave de API sendgrid que você registrou anteriormente.
  9. Para Uso de chave, selecione Assinatura.
  10. Selecione Criar.

Criar modelo do SendGrid

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

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

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

  3. Para começar a editar seu novo modelo, selecione o modelo que é, em seguida, Verification emailselecione Adicionar Versão.

  4. Selecione Modelo em Branco e, em seguida, Editor de Código.

  5. No editor HTML, cole o modelo HTML a seguir ou use o seu próprio. Os {{otp}} parâmetros e os {{email}} parâmetros 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. Clique em Salvar.

  9. Retorne à página Modelos Transacionais selecionando a seta para trás.

  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 seus arquivos XML de política personalizados. Recomendamos que você use uma política personalizada de verificação de email personalizada de exemplo disponível no GitHub. DisplayControl_TrustFrameworkExtensions.xml usa TrustFrameworkExtensions.xml como seu arquivo base; portanto, certifique-se de incluir os arquivos TrustFrameworkBase.xml, TrustFrameworkLocalization.xml e TrustFrameworkExtensions.xml do SocialAndLocalAccountspacote inicial em sua configuração.

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 OTP (senha única).

<!-- 
<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, consulte transformações de declarações JSON.

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

  • Atualize o valor do template_id InputParameter com a identificação do modelo transacional SendGrid que você criou anteriormente em Criar modelo 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

    Esse endereço de email deve ser verificado 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 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. Colete o tipo de declaração de endereço email do usuário.

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

    Ação de enviar email com código de verificação

  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 GenerateOtp perfil técnico gera um código para o endereço de email. O VerifyOtp perfil técnico verifica o código associado ao endereço de email. Você pode alterar a configuração do formato e a expiração da senha única. Para obter mais informações sobre perfis técnicos OTP, consulte Definir um perfil técnico de senha única.

Observação

Os 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 gera um novo código OTP em uma nova sessão do navegador, ele substitui o código OTP anterior.

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

<!--
<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 SendGrid). Para obter mais informações sobre perfis técnicos RESTful, consulte Definir um perfil técnico RESTful.

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

<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ê usou uma versão anterior da política do Azure AD B2C, esses perfis técnicos usam DisplayClaims com uma referência ao DisplayControl.

Para obter mais informações, consulte o 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, você deve enviar cadeias de caracteres localizadas para SendGrid ou seu provedor de email. Por exemplo, você pode localizar o assunto de email, o corpo, a mensagem de código ou a assinatura do email. Para fazer isso, você pode usar 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. Em 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 seguinte elemento Localization .

    <!--
    <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. Adicione o seguinte LocalizedString aos 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="VerificationCode" StringId="DisplayName">Verification Code</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="VerificationCode" StringId="UserHelpText">Verification code received in the email.</LocalizedString>
    <LocalizedString ElementType="ClaimType" ElementId="VerificationCode" 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>