Compartir vía


Llamada a una API de REST mediante la directiva personalizada de Azure Active Directory B2C

La directiva personalizada de Azure Active Directory B2C (Azure AD B2C) permite interactuar con la lógica de la aplicación que se implementa fuera de Azure AD B2C. Para ello, realice una llamada HTTP a un punto de conexión. Las directivas personalizadas de Azure AD B2C proporcionan un perfil técnico RESTful para este fin. Con esta funcionalidad, puede implementar características que no están disponibles en la directiva personalizada de Azure AD B2C.

En este artículo aprenderá a:

  • Cree e implemente una aplicación de Node.js de ejemplo para usarla como un servicio RESTful.

  • Realice una llamada HTTP al servicio RESTful Node.js mediante el perfil técnico de RESTful.

  • Controle o informe de un error que devuelve un servicio RESTful a su directiva personalizada.

Información general del escenario

En Crear ramas en el recorrido del usuario mediante directivas personalizadas de Azure AD B2C, los usuarios que seleccionan Cuenta personal deben proporcionar un código de acceso de invitación válido para continuar. Usamos un código de acceso estático, pero las aplicaciones del mundo real no funcionan de esta manera. Si el servicio que emite los códigos de acceso es externo a la directiva personalizada, deberá realizar una llamada a dicho servicio y pasar el código de acceso introducido por el usuario para su validación. Si el código de acceso es válido, el servicio devuelve una respuesta HTTP 200 OK y Azure AD B2C emite el token JWT. En caso contrario, el servicio devuelve una respuesta HTTP 409 Conflict y el usuario debe volver a escribir un código de acceso.

A flowchart of calling a R E S T A P I.

Requisitos previos

Nota

Este artículo forma parte de la Serie de guías paso a paso para crear y ejecutar sus propias directivas personalizadas en Azure Active Directory B2C. Le recomendamos que empiece esta serie por el primer artículo.

Paso 1: Crear e implementar una aplicación de Node.js

Debe implementar una aplicación, que sirve como aplicación externa. A continuación, la directiva personalizada realiza una llamada HTTP a esta aplicación.

Paso 1.1: Crear la aplicación de Node.js

  1. Cree una carpeta para hospedar la aplicación de Node, como access-code-app.

  2. En el terminal, cambie el directorio a la carpeta de la aplicación de Node, como cd access-code-app, y ejecute npm init -y. Este comando crea un archivo package.json predeterminado para el proyecto de Node.js.

  3. En el terminal, ejecute npm install express body-parser. Este comando instala el marco Express y el paquete del analizador de cuerpo.

  4. En el proyecto, cree el archivo index.js.

  5. En VS Code, abra el archivo index.js y, a continuación, agregue el siguiente código:

        const express = require('express');
        let bodyParser = require('body-parser')
        //Create an express instance
        const app = express();
    
        app.use( bodyParser.json() );       // to support JSON-encoded bodies
        app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
          extended: true
        }));
    
    
        app.post('/validate-accesscode', (req, res) => {
            let accessCode = '88888';
            if(accessCode == req.body.accessCode){
                res.status(200).send();
            }else{
                let errorResponse = {
                    "version" :"1.0",
                    "status" : 409,
                    "code" : "errorCode",
                    "requestId": "requestId",
                    "userMessage" : "The access code you entered is incorrect. Please try again.",
                    "developerMessage" : `The provided code ${req.body.accessCode} does not match the expected code for user.`,
                    "moreInfo" :"https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
                };
                res.status(409).send(errorResponse);                
            }
        });
    
        app.listen(80, () => {
            console.log(`Access code service listening on port !` + 80);
        });
    

    Puede observar que cuando un usuario envía un código de acceso incorrecto, puede devolver un error directamente desde la API de REST. Las directivas personalizadas permiten devolver un mensaje de error HTTP 4xx, por ejemplo, un código de estado de respuesta 400 (solicitud incorrecta) o 409 (conflicto) con un cuerpo JSON de respuesta con formato como se muestra en la variable errorResponse. El origen de accessCode en la aplicación podría leerse desde una base de datos. Obtenga más información sobre la devolución del mensaje de error de validación.

  6. Para probar que la aplicación funciona según lo previsto, siga estos pasos:

    1. En el terminal, ejecute el comando node index.js para iniciar el servidor de la aplicación.
    2. Para realizar una solicitud POST similar a la que se muestra en este ejemplo, puede usar un cliente HTTP como Microsoft PowerShell o Postman:
        POST http://localhost/validate-accesscode HTTP/1.1
        Host: localhost
        Content-Type: application/x-www-form-urlencoded
    
        accessCode=user-code-code
    

    Reemplace user-code-code con una entrada de código de acceso por el usuario, como 54321. Si usa PowerShell, ejecute el siguiente script.

        $accessCode="54321"
        $endpoint="http://localhost/validate-accesscode"
        $body=$accessCode
        $response=Invoke-RestMethod -Method Post -Uri $endpoint -Body $body
        echo $response
    

    Si usa un código de acceso incorrecto, la respuesta es similar al siguiente fragmento de código JSON:

        {
            "version": "1.0",
            "status": 409,
            "code": "errorCode",
            "requestId": "requestId",
            "userMessage": "The access code you entered is incorrect. Please try again.",
            "developerMessage": "The provided code 54321 does not match the expected code for user.",
            "moreInfo": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
        }
    

En este momento, está listo para implementar la aplicación de Node.js.

Paso 1.2: Implementar la aplicación de Node.js en Azure App Service

Para que la directiva personalizada llegue a la aplicación de Node.js, debe ser accesible, por lo que necesita implementarla. En este artículo, se implementa la aplicación mediante Azure App Service, pero se usa un enfoque de hospedaje alternativo.

Siga los pasos descritos en Implementar una aplicación en Azure para implementar la aplicación de Node.js en Azure. Para el nombre de la aplicación, use un nombre descriptivo como custompolicyapi. Por lo tanto:

  • La dirección URL de la aplicación es similar a https://custompolicyapi.azurewebsites.net.

  • El punto de conexión de servicio es similar a https://custompolicyapi.azurewebsites.net/validate-accesscode.

Puede probar la aplicación que ha implementado mediante un cliente HTTP como Microsoft PowerShell o Postman. Esta vez, use la dirección URL https://custompolicyapi.azurewebsites.net/validate-accesscode como punto de conexión.

Paso 2: Llamada a la API de REST

Ahora que la aplicación se está ejecutando, debe realizar una llamada HTTP desde la directiva personalizada. La directiva personalizada de Azure AD B2C proporciona un perfil técnico RESTful que se usa para llamar a un servicio externo.

Paso 2.1: Definir un perfil técnico de RESTful

En el archivo ContosoCustomPolicy.XML, busque la sección ClaimsProviders y defina un nuevo perfil técnico RESTful mediante el código siguiente:

    <!--<ClaimsProviders>-->
        <ClaimsProvider>
            <DisplayName>HTTP Request Technical Profiles</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="ValidateAccessCodeViaHttp">
                    <DisplayName>Check that the user has entered a valid access code by using Claims Transformations</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://custompolicyapi.azurewebsites.net/validate-accesscode</Item>
                        <Item Key="SendClaimsIn">Body</Item>
                        <Item Key="AuthenticationType">None</Item>
                        <Item Key="AllowInsecureAuthInProduction">true</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="accessCode" PartnerClaimType="accessCode" />
                    </InputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    <!--</ClaimsProviders>-->

Desde el protocolo, puede observar que configuramos el perfil técnico para usar RestfulProvider. También puede observar la siguiente información en la sección de metadatos:

  • ServiceUrl representa el punto de conexión de la API. Su valor es https://custompolicyapi.azurewebsites.net/validate-accesscode. Si implementó la aplicación de Node.js mediante un método alternativo, asegúrese de actualizar el valor del punto de conexión.

  • SendClaimsIn especifica cómo se envían las notificaciones de entrada al proveedor de notificaciones RESTful. Valores posibles: Body (default), Form, Header, Url o QueryString. Cuando se usa Body, como en este artículo, se invoca el verbo HTTP POST y los datos que se envían a la API si tienen formato de pares clave-valor en el cuerpo de la solicitud. Obtenga información sobre cómo invocar el verbo HTTP GET y pasar datos como cadena de consulta.

  • AuthenticationType especifica el tipo de autenticación que realiza el proveedor de notificaciones RESTful. Nuestro proveedor de notificaciones RESTful llama a un punto de conexión desprotegido, por lo que establecemos AuthenticationType en Ninguno. Si establece el tipo de autenticación en Bearer, debe agregar un elemento CryptographicKeys, que especifica el almacenamiento del token de acceso. Obtenga más información sobre los tipos de autenticación que admite el proveedor de notificaciones RESTful.

  • El atributo PartnerClaimType de InputClaim especifica cómo se reciben los datos en la API.

Paso 2.2: Actualizar el perfil técnico de validación

En Crear bifurcación en el recorrido del usuario mediante la directiva personalizada de Azure AD B2C, validó accessCode mediante una transformación de notificaciones. En este artículo, validará accessCode mediante una llamada HTTP a un servicio externo. Por lo tanto, deberá actualizar la directiva personalizada para reflejar el nuevo enfoque.

Busque el perfil técnico AccessCodeInputCollector y actualice el ReferenceId del elemento ValidationTechnicalProfile a ValidateAccessCodeViaHttp:

de:

    <ValidationTechnicalProfile ReferenceId="CheckAccessCodeViaClaimsTransformationChecker"/>

a:

    <ValidationTechnicalProfile ReferenceId="ValidateAccessCodeViaHttp"/>

En este momento, el perfil técnico con IdCheckAccessCodeViaClaimsTransformationChecker no es necesario y se puede quitar.

Paso 3: Carga del archivo de directiva personalizado

Asegúrese de que la aplicación de Node.js se está ejecutando y, a continuación, siga los pasos descritos en Cargar archivo de directiva personalizado para cargar el archivo de directiva. Si va a cargar un archivo con el mismo nombre que el que ya está en el portal, asegúrese de seleccionar Sobrescribir la directiva personalizada si ya existe.

Paso 4: Prueba de la directiva personalizada

Siga los pasos descritos en Probar la directiva personalizada para probar la directiva personalizada:

  1. En Tipo de cuenta, seleccione Cuenta personal
  2. Escriba el resto de los detalles según sea necesario y, a continuación, seleccione Continuar. Se ve una nueva pantalla.
  3. En Código de acceso, escriba 88888 y, a continuación, seleccione Continuar. Una vez finalizada la ejecución de la directiva, se le redirigirá a https://jwt.ms y verá un token JWT descodificado. Si repite el procedimiento y escribe otro código de acceso, cualquiera que no sea 88888, verá un el siguiente error: El código de acceso que especificó no es correcto. Vuelva a intentarlo.

Paso 5: Habilitar el modo de depuración

Durante el desarrollo, es posible que desee ver errores detallados enviados por la API, como developerMessage y moreInfo. En este caso, debe habilitar el modo de depuración en el proveedor técnico RESTful.

  1. Busque el proveedor técnico ValidateAccessCodeViaHttp y agregue el siguiente elemento en el metadata del proveedor técnico:

        <Item Key="DebugMode">true</Item>
    
  2. Guarde los cambios y cargue el archivo de directiva.

  3. Prueba de la directiva personalizada. Asegúrese de usar una entrada incorrecta para el código de acceso. Se ve un error similar al que se muestra en esta captura de pantalla:

    A screenshot error when you enable debug mode.

Control de cargas JSON de solicitud compleja

Si la API de REST a la que llama requiere que envíe una carga JSON compleja, puede crear la carga mediante transformaciones de notificaciones JSON de GenerateJson. Una vez que genere la carga, puede usar ClaimUsedForRequestPayload la opción de metadatos para el nombre de la notificación que contiene la carga JSON.

Por ejemplo, use la siguiente transformación de notificaciones para generar una carga JSON:

    <ClaimsTransformation Id="GenerateRequestBodyClaimsTransformation" TransformationMethod="GenerateJson">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="customerEntity.email" />
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="customerEntity.userObjectId" />
            <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="customerEntity.firstName" />
            <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="customerEntity.lastName" />
            <InputClaim ClaimTypeReferenceId="accessCode" TransformationClaimType="customerEntity.accessCode" />
        </InputClaims>
        <InputParameters>
            <InputParameter Id="customerEntity.role.name" DataType="string" Value="Administrator" />
            <InputParameter Id="customerEntity.role.id" DataType="long" Value="1" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="requestBodyPayload" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>

ClaimsTransformation genera el siguiente objeto JSON:

{
   "customerEntity":{
      "email":"john.s@contoso.com",
      "userObjectId":"01234567-89ab-cdef-0123-456789abcdef",
      "firstName":"John",
      "lastName":"Smith",
      "accessCode":"88888",
      "role":{
         "name":"Administrator",
         "id": 1
      }
   }
}

A continuación, actualice Metadata, InputClaimsTransformations y InputClaims del proveedor técnico RESTful, como se muestra a continuación:

    <Metadata>
        <Item Key="ClaimUsedForRequestPayload">requestBodyPayload</Item>
        <!--Other Metadata items -->
    </Metadata>
    
    <!--Execute your InputClaimsTransformations to generate your request Payload-->
    <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateRequestBodyClaimsTransformation" />
    </InputClaimsTransformations>
    
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="requestBodyPayload" />
    </InputClaims>

Recibir datos de la API de REST

Si la API de REST devuelve datos, que quieres incluir como notificaciones en la directiva, puedes recibirlos especificando notificaciones en el elemento del perfil técnico RESTful OutputClaims. Si el nombre de la notificación definida en la directiva es diferente del nombre definido en la API REST, debes asignar estos nombres mediante el atributo PartnerClaimType.

Sigue los pasos descritos en Recepción de datos para obtener información sobre cómo dar formato a los datos que espera la directiva personalizada, cómo controlar valores NULL y cómo analizar el cuerpo JSON anidado de la API.

Pasos siguientes

A continuación, aprenda: