Compartir a través de


Configuración de un flujo de credenciales de contraseña de propietario de recursos en Azure Active Directory B2C

Importante

A partir del 1 de mayo de 2025, Azure AD B2C ya no estará disponible para la compra por parte de nuevos clientes. Obtenga más información en nuestras preguntas más frecuentes.

Antes de empezar, use el selector Elegir un tipo de directiva en la parte superior de esta página para elegir el tipo de directiva que está configurando. Azure Active Directory B2C ofrece dos métodos para definir cómo interactúan los usuarios con las aplicaciones: a través de flujos de usuario predefinidos o mediante directivas personalizadas totalmente configurables. Los pasos necesarios en este artículo son diferentes para cada método.

En Azure Active Directory B2C (Azure AD B2C), el flujo de credenciales de contraseña del propietario del recurso (ROPC) es un flujo de autenticación estándar de OAuth. En este flujo, una aplicación, también conocida como usuario de confianza, intercambia credenciales válidas por tokens. Las credenciales incluyen un ID de usuario y una contraseña. Los tokens devueltos son un token de identificador, un token de acceso y un token de actualización.

Advertencia

Le recomendamos que no utilice el flujo ROPC. En la mayoría de los escenarios, hay alternativas más seguras disponibles y recomendadas. Este flujo requiere un grado muy alto de confianza en la aplicación y conlleva riesgos que no están presentes en otros flujos. Solo debe usar este flujo cuando no se puedan usar otros más seguros.

Notas de flujo de ROPC

En Azure Active Directory B2C (Azure AD B2C), se admiten las siguientes opciones:

  • Cliente nativo: la interacción del usuario durante la autenticación se produce cuando el código se ejecuta en un dispositivo del lado del usuario. El dispositivo puede ser una aplicación móvil que se ejecute en un sistema operativo nativo, como Android e iOS.
  • Flujo de cliente público: solo se envían las credenciales de usuario recopiladas por una aplicación en la llamada a la API. Las credenciales de la aplicación no se envían.
  • Agregar nuevas notificaciones: el contenido del token de ID se puede cambiar para agregar nuevas notificaciones.

No se admiten los siguientes flujos:

  • De servidor a servidor: el sistema de protección de identidad necesita una dirección IP confiable recopilada de la persona que llama (el cliente nativo) como parte de la interacción. En una llamada a la API del lado del servidor, solo se utiliza la dirección IP del servidor. Si se supera un umbral dinámico de autenticaciones fallidas, el sistema de protección de identidad puede identificar una dirección IP repetida como atacante.
  • Flujo de cliente confidencial: se valida el identificador de cliente de la aplicación, pero no se valida el secreto de la aplicación.

Al utilizar el flujo ROPC, tenga en cuenta las siguientes limitaciones:

Registrar una aplicación

Para registrar una aplicación en el inquilino de Azure AD B2C, puede usar la nueva experiencia unificada Registros de aplicaciones o bien nuestra experiencia anterior de Aplicaciones (heredado). Obtenga más información sobre la nueva experiencia.

  1. Inicie sesión en Azure Portal.
  2. Asegúrese de estar utilizando el directorio que contiene su instancia de Azure AD B2C.
    1. Seleccione el icono Directorios y suscripciones en la barra de herramientas del portal.
    2. En la página Configuración del portal | Directorios y suscripciones, busque el directorio de Azure AD B2C en la lista Nombre de directorio y seleccione Cambiar.
  3. En Azure Portal, busque y seleccione Azure AD B2C
  4. Seleccione Registros de aplicaciones y luego Nuevo registro.
  5. Escriba un Nombre para la aplicación. Por ejemplo, ROPC_Auth_app.
  6. Deje los demás valores como están y, a continuación, seleccione Registrar.
  7. Registre el identificador de aplicación (cliente) para usarlo en un paso posterior.
  8. En Administrar, seleccione Autenticación.
  9. Seleccione Probar la nueva experiencia (si se muestra).
  10. En Configuración avanzada y en la sección Habilitar los siguientes flujos móviles y de escritorio, seleccione para tratar la aplicación como un cliente público. Esta configuración es necesaria para el flujo ROPC.
  11. Haga clic en Guardar.
  12. En el menú de la izquierda, seleccione Manifiesto para abrir el editor de manifiestos.
  13. Establezca el atributo oauth2AllowImplicitFlow en true. Si el atributo no existe, agréguelo:
    "oauth2AllowImplicitFlow": true,
    
  14. Haga clic en Guardar.

Creación de un flujo de usuario propietario del recurso

  1. Inicie sesión en Azure Portal como Administrador de flujo de usuario de identificador externo del inquilino de Azure AD B2C.
  2. Si tiene acceso a varios inquilinos, seleccione el icono Configuración en el menú superior para cambiar a su inquilino de Azure AD B2C desde el menú Directorios y suscripciones.
  3. En Azure Portal, busque y seleccione Azure AD B2C.
  4. Seleccione Flujos de usuario y, a continuación, Nuevo flujo de usuario.
  5. Seleccione Iniciar sesión con credenciales de contraseña de propietario del recurso (ROPC).
  6. En Versión, asegúrese de que la opción Vista previa esté seleccionada y, a continuación, seleccione Crear.
  7. Proporcione un nombre para el flujo de usuario, como ROPC_Auth.
  8. En Notificaciones de aplicación, seleccione Mostrar más.
  9. Seleccione las notificaciones de aplicación que necesita para su aplicación, como Nombre para mostrar, Dirección de correo electrónico y Proveedor de identidad.
  10. Seleccione Aceptar y, a continuación, Crear.

Prerrequisito

Si aún no lo ha hecho, obtenga información sobre cómo usar el paquete de inicio de directivas personalizadas en Introducción a las directivas personalizadas en Active Directory B2C.

Creación de una directiva de propietario de recursos

  1. Abra el archivo TrustFrameworkExtensions.xml .

  2. En el elemento BuildingBlocks , busque el elemento ClaimsSchema y, a continuación, agregue los siguientes tipos de notificaciones:

    <ClaimsSchema>
      <ClaimType Id="logonIdentifier">
        <DisplayName>User name or email address that the user can use to sign in</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="resource">
        <DisplayName>The resource parameter passes to the ROPC endpoint</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokenIssuedOnDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
      <ClaimType Id="refreshTokensValidFromDateTime">
        <DisplayName>An internal parameter used to determine whether the user should be permitted to authenticate again using their existing refresh token.</DisplayName>
        <DataType>string</DataType>
      </ClaimType>
    </ClaimsSchema>
    
  3. Después de ClaimsSchema, agregue un elemento ClaimsTransformations y sus elementos secundarios al elemento BuildingBlocks :

    <ClaimsTransformations>
      <ClaimsTransformation Id="CreateSubjectClaimFromObjectID" TransformationMethod="CreateStringClaim">
        <InputParameters>
          <InputParameter Id="value" DataType="string" Value="Not supported currently. Use oid claim." />
        </InputParameters>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="sub" TransformationClaimType="createdClaim" />
        </OutputClaims>
      </ClaimsTransformation>
    
      <ClaimsTransformation Id="AssertRefreshTokenIssuedLaterThanValidFromDate" TransformationMethod="AssertDateTimeIsGreaterThan">
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" TransformationClaimType="leftOperand" />
          <InputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" TransformationClaimType="rightOperand" />
        </InputClaims>
        <InputParameters>
          <InputParameter Id="AssertIfEqualTo" DataType="boolean" Value="false" />
          <InputParameter Id="AssertIfRightOperandIsNotPresent" DataType="boolean" Value="true" />
        </InputParameters>
      </ClaimsTransformation>
    </ClaimsTransformations>
    
  4. Busque el elemento ClaimsProvider que tiene un DisplayName de Local Account SignIn y agregue el siguiente perfil técnico:

    <TechnicalProfile Id="ResourceOwnerPasswordCredentials-OAUTH2">
      <DisplayName>Local Account SignIn</DisplayName>
      <Protocol Name="OpenIdConnect" />
      <Metadata>
        <Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item>
        <Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item>
        <Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item>
        <Item Key="DiscoverMetadataByTokenIssuer">true</Item>
        <Item Key="ValidTokenIssuerPrefixes">https://sts.windows.net/</Item>
        <Item Key="METADATA">https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration</Item>
        <Item Key="authorization_endpoint">https://login.microsoftonline.com/{tenant}/oauth2/token</Item>
        <Item Key="response_types">id_token</Item>
        <Item Key="response_mode">query</Item>
        <Item Key="scope">email openid</Item>
        <Item Key="grant_type">password</Item>
      </Metadata>
      <InputClaims>
        <InputClaim ClaimTypeReferenceId="logonIdentifier" PartnerClaimType="username" Required="true" DefaultValue="{OIDC:Username}"/>
        <InputClaim ClaimTypeReferenceId="password" Required="true" DefaultValue="{OIDC:Password}" />
        <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" />
        <InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" />
        <InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" />
        <InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFrameworkAppId" />
        <InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFrameworkAppId" />
      </InputClaims>
      <OutputClaims>
        <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" />
        <OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" />
      </OutputClaims>
      <OutputClaimsTransformations>
        <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
      </OutputClaimsTransformations>
      <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    

    Reemplace el valor de DefaultValue de client_id por el identificador de aplicación de la aplicación ProxyIdentityExperienceFramework que creó en el tutorial de requisitos previos. A continuación, reemplace DefaultValue de resource_id por el identificador de aplicación de la aplicación IdentityExperienceFramework que también creó en el tutorial de requisitos previos.

  5. Agregue los siguientes elementos ClaimsProvider con sus perfiles técnicos al elemento ClaimsProviders :

    <ClaimsProvider>
      <DisplayName>Azure Active Directory</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="AAD-UserReadUsingObjectId-CheckRefreshTokenDate">
          <Metadata>
            <Item Key="Operation">Read</Item>
            <Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
          </Metadata>
          <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" Required="true" />
          </InputClaims>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokensValidFromDateTime" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AssertRefreshTokenIssuedLaterThanValidFromDate" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromObjectID" />
          </OutputClaimsTransformations>
          <IncludeTechnicalProfile ReferenceId="AAD-Common" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Session Management</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="SM-RefreshTokenReadAndSetup">
          <DisplayName>Trustframework Policy Engine Refresh Token Setup Technical Profile</DisplayName>
          <Protocol Name="None" />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" />
            <OutputClaim ClaimTypeReferenceId="refreshTokenIssuedOnDateTime" />
          </OutputClaims>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
    <ClaimsProvider>
      <DisplayName>Token Issuer</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="JwtIssuer">
          <Metadata>
            <!-- Point to the redeem refresh token user journey-->
            <Item Key="RefreshTokenUserJourneyId">ResourceOwnerPasswordCredentials-RedeemRefreshToken</Item>
          </Metadata>
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    
  6. Agregue un elemento UserJourneys y sus elementos secundarios al elemento TrustFrameworkPolicy :

    <UserJourney Id="ResourceOwnerPasswordCredentials">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="ResourceOwnerFlow" TechnicalProfileReferenceId="ResourceOwnerPasswordCredentials-OAUTH2" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    <UserJourney Id="ResourceOwnerPasswordCredentials-RedeemRefreshToken">
      <PreserveOriginalAssertion>false</PreserveOriginalAssertion>
      <OrchestrationSteps>
        <OrchestrationStep Order="1" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="RefreshTokenSetupExchange" TechnicalProfileReferenceId="SM-RefreshTokenReadAndSetup" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="2" Type="ClaimsExchange">
          <ClaimsExchanges>
            <ClaimsExchange Id="CheckRefreshTokenDateFromAadExchange" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId-CheckRefreshTokenDate" />
          </ClaimsExchanges>
        </OrchestrationStep>
        <OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
      </OrchestrationSteps>
    </UserJourney>
    
  7. En la página Directivas personalizadas del inquilino de Azure AD B2C, seleccione Directiva de carga.

  8. Habilite Sobrescribir la directiva si existe y, a continuación, busque y seleccione el archivo TrustFrameworkExtensions.xml .

  9. Seleccione Cargar.

Creación de un archivo de usuario de confianza

A continuación, actualice el archivo de usuario de confianza que inicia el recorrido del usuario que ha creado:

  1. Haga una copia de SignUpOrSignin.xml archivo en su directorio de trabajo y cámbiele el nombre a ROPC_Auth.xml.

  2. Abra el nuevo archivo y cambie el valor del atributo PolicyId para TrustFrameworkPolicy a un valor único. El ID de política es el nombre de la póliza. Por ejemplo, B2C_1A_ROPC_Auth.

  3. Cambie el valor del atributo ReferenceId en DefaultUserJourney a ResourceOwnerPasswordCredentials.

  4. Cambie el elemento OutputClaims para que solo contenga las siguientes notificaciones:

    <OutputClaim ClaimTypeReferenceId="sub" />
    <OutputClaim ClaimTypeReferenceId="objectId" />
    <OutputClaim ClaimTypeReferenceId="displayName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="givenName" DefaultValue="" />
    <OutputClaim ClaimTypeReferenceId="surname" DefaultValue="" />
    
  5. En la página Directivas personalizadas del inquilino de Azure AD B2C, seleccione Directiva de carga.

  6. Habilite Sobrescribir la directiva si existe y, a continuación, busque y seleccione el archivo ROPC_Auth.xml .

  7. Seleccione Cargar.

Pruebe el flujo ROPC

Use su aplicación de desarrollo de API favorita para generar una llamada a la API y revise la respuesta para depurar la directiva. Construya una llamada como este ejemplo con la siguiente información como cuerpo de la solicitud POST:

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • Reemplace <tenant-name> por el nombre del inquilino de Azure AD B2C.
  • Reemplácelo B2C_1A_ROPC_Auth por el nombre completo de la política de credenciales de contraseña del propietario del recurso.
Clave Importancia
nombre de usuario user-account
contraseña password1
tipo_de_subvención contraseña
alcance OpenID application-id offline_access
ID de cliente application-id
tipo_de_respuesta id_token de tokens
  • Reemplácelo user-account por el nombre de una cuenta de usuario en el inquilino.
  • Reemplácelo password1 por la contraseña de la cuenta de usuario.
  • Reemplácelo application-id por el ID de aplicación del registro ROPC_Auth_app .
  • Offline_access es opcional si desea recibir un token de actualización.

La solicitud POST real tiene un aspecto similar al siguiente ejemplo:

POST /<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token HTTP/1.1
Host: <tenant-name>.b2clogin.com
Content-Type: application/x-www-form-urlencoded

username=contosouser.outlook.com.ws&password=Passxword1&grant_type=password&scope=openid+00001111-aaaa-2222-bbbb-3333cccc4444+offline_access&client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token+id_token

Una respuesta correcta con acceso sin conexión es similar al siguiente ejemplo:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki...",
    "token_type": "Bearer",
    "expires_in": "3600",
    "refresh_token": "eyJraWQiOiJacW9pQlp2TW5pYVc2MUY0TnlfR3REVk1EVFBLbUJLb0FUcWQ1ZWFja1hBIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6Ij...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9YQjNhdTNScWhUQWN6R0RWZDM5djNpTmlyTWhqN2wxMjIySnh6TmgwRlki..."
}

Canjear un token de actualización

Construya una llamada POST como la que se muestra aquí. Utilice la información de la tabla siguiente como cuerpo de la solicitud:

https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token

  • Reemplace <tenant-name> por el nombre del inquilino de Azure AD B2C.
  • Reemplácelo B2C_1A_ROPC_Auth por el nombre completo de la política de credenciales de contraseña del propietario del recurso.
Clave Importancia
tipo_de_subvención token de actualización
tipo_de_respuesta token de identificación
ID de cliente application-id
recurso application-id
token de actualización refresh-token
  • Reemplácelo application-id por el ID de aplicación del registro ROPC_Auth_app .
  • Reemplácelo refresh-token por el refresh_token que se devolvió en la respuesta anterior.

Una respuesta correcta es similar al siguiente ejemplo:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhT...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQn...",
    "token_type": "Bearer",
    "not_before": 1533672990,
    "expires_in": 3600,
    "expires_on": 1533676590,
    "resource": "bef2222d56-552f-4a5b-b90a-1988a7d634c3",
    "id_token_expires_in": 3600,
    "profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiI1MTZmYzA2NS1mZjM2LTRiOTMtYWE1YS1kNmVlZGE3Y2JhYzgiLCJzdWIiOm51bGwsIm5hbWUiOiJEYXZpZE11IiwicHJlZmVycmVkX3VzZXJuYW1lIjpudWxsLCJpZHAiOiJMb2NhbEFjY291bnQifQ",
    "refresh_token": "eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAi...",
    "refresh_token_expires_in": 1209600
}

Solución de problemas

La aplicación proporcionada no está configurada para permitir el flujo implícito "OAuth"

  • Síntoma : ejecuta el flujo ROPC y recibe el siguiente mensaje: AADB2C90057: La aplicación proporcionada no está configurada para permitir el flujo implícito 'OAuth'.
  • Causas posibles : el flujo implícito no está permitido para la aplicación.
  • Solución: Al crear el registro de la aplicación en Azure AD B2C, debe editar manualmente el manifiesto de la aplicación y establecer el valor de la oauth2AllowImplicitFlow propiedad en true. Después de configurar la oauth2AllowImplicitFlow propiedad, el cambio puede tardar unos minutos (normalmente no más de cinco) en surtir efecto.

Usar un SDK nativo o App-Auth

Azure AD B2C cumple los estándares de OAuth 2.0 para las credenciales de contraseña del propietario de recursos de cliente público y debe ser compatible con la mayoría de los SDK de cliente. Para obtener la información más reciente, consulte SDK de aplicaciones nativas para OAuth 2.0 y OpenID Connect que implementan procedimientos recomendados modernos.