Esercizio - Implementare dati multi-tenant

Completato

Questo esercizio illustra i processi seguenti:

  • Installazione di Database di Azure per PostgreSQL nel modello di distribuzione del server.
  • Creazione di un database con dati di inventario di esempio.
  • Integrazione del server con Microsoft Entra ID.
  • Implementazione di una semplice applicazione basata su Node.js che esegue query sul database basandosi sull'autenticazione di Microsoft Entra.

Nota

Questo esercizio illustra un approccio semplificato per supportare più tenant emulando la funzionalità multi-tenancy del database di Azure per il modello di distribuzione PostgreSQL Hyperscale. Offre anche un approccio semplificato per l'implementazione dell'autenticazione di Microsoft Entra in scenari multi-tenant basandosi sulla funzionalità B2B di Microsoft Entra. Microsoft Entra ID supporta direttamente le applicazioni multi-tenant, ma una trattazione dettagliata di questo argomento esula dagli scopi di questo modulo.

In questo esercizio si vedrà come:

  • Creare un'istanza del server di Database di Azure per PostgreSQL.
  • Connettersi al server di Database di Azure per PostgreSQL.
  • Creare un database e tabelle di esempio.
  • Integrare il server di Database di Azure per PostgreSQL con Microsoft Entra ID.
  • Registrare un'applicazione con Microsoft Entra ID.
  • Implementare un'applicazione semplice basata su Node.js integrata in Microsoft Entra.
  • Convalidare la funzionalità dell'applicazione basata su Node.js.

Prerequisiti

Per eseguire questo esercizio, è necessario:

  • Una sottoscrizione di Azure.
  • Un account Microsoft o un account Microsoft Entra con il ruolo Amministratore globale nel tenant di Microsoft Entra associato alla sottoscrizione di Azure e con il ruolo Proprietario o Collaboratore nella sottoscrizione di Azure.
  • Il primo esercizio del modulo è stato completato.

Creare un'istanza del server di Database di Azure per PostgreSQL

Si inizierà creando un'istanza del server di Database di Azure per PostgreSQL:

  1. Se necessario, avviare un Web browser, passare al portale di Azure ed eseguire l'accesso alla sottoscrizione di Azure che verrà usata in questo modulo.

  2. Usare la casella di testo Cerca risorse, servizi e documentazione nella parte superiore della pagina del portale di Azure e cercare Database di Azure per PostgreSQL, quindi nella sezione Servizi selezionare Database di Azure per PostgreSQL nell'elenco dei risultati.

  3. Nel pannello Server database di Azure per PostgreSQL selezionare Crea.

  4. Nel pannello Selezionare il database di Azure per l'opzione di distribuzione PostgreSQL, nel riquadro Server singolo, per Tipo di risorsa selezionare Server singolo.

  5. Seleziona Crea.

  6. Nella scheda Informazioni di base del pannello Server singolo configurare le impostazioni seguenti e quindi selezionare Rivedi e crea, lasciando i valori predefiniti per tutte le altre impostazioni:

    Impostazione Configurazione
    Subscription Selezionare il nome della sottoscrizione di Azure che verrà usata in questo modulo.
    Gruppo di risorse Creare un nuovo gruppo di risorse denominato postgresql-db-RG.
    Nome server Immettere un nome univoco costituito da lettere minuscole, cifre o trattini e che inizia con una lettera.
    Origine dati Selezionare Nessuno.
    Titolo Selezionare l'area di Azure più vicina alla località dell'ambiente lab in cui è possibile creare istanze di Database di Azure per PostgreSQL.
    Versione Selezionare 11.
    Calcolo e archiviazione Selezionare il collegamento Configura server. Nel pannello Configura selezionare Basic, impostare il valore di vCore su 1 e Archiviazione su 5 GB, quindi selezionare OK.
    Nome utente amministratore Immettere student.
    Password Immettere Pa55w0rd1234.

    Screenshot of the Basics tab of the server blade in the Azure portal.

  7. Nella scheda Rivedi e crea del pannello Server singolo selezionare Crea.

  8. Attendere che venga completato il provisioning. Possono essere necessari circa cinque minuti.

    Nota

    Il processo di provisioning crea automaticamente un database denominato postgres nel server di destinazione.

Connettersi al server di Database di Azure per PostgreSQL

Dopo aver effettuato il provisioning del server di Database di Azure per PostgreSQL, ci si connetterà al server usando lo strumento psql.

  1. Nel pannello Panoramica di Microsoft.PostgreSQLServer.createPostgreSqlServer selezionare Vai alla risorsa.

  2. Nel pannello Distribuzione selezionare Sicurezza connessione della sezione Impostazioni nel menu verticale.

  3. Nel pannello Sicurezza connessione impostare Consenti l'accesso a Servizi di Azure su , selezionare + Aggiungi IP client, impostare Imponi connessione SSL su DISABILITATO, quindi selezionare Salva.

    Nota

    Queste impostazioni consentiranno la connettività al database dal computer e dalle applicazioni in esecuzione in Azure.

    Nota

    La disabilitazione dell'imposizione SSL ha il solo scopo di semplificare gli esercizi successivi. In generale, è consigliabile mantenere questa impostazione abilitata.

  4. Nella finestra del browser che visualizza il portale di Azure con il pannello Distribuzione selezionare Panoramica nel menu verticale.

  5. Nella sezione Informazioni di base identificare le voci accanto alle etichette Nome server e Nome utente amministratore e prendere nota dei relativi valori.

    Nota

    Si noti che il nome utente include il simbolo @ seguito dal nome del server specificato nell'attività precedente.

  6. Nella finestra del browser che visualizza il portale di Azure con il pannello Server singolo di Database di Azure per PostgreSQL selezionare Stringhe di connessione nella sezione Impostazioni nel menu verticale.

  7. Nell'elenco delle stringhe di connessione copiare il valore della stringa di connessione psql e registrarlo, in modo da poterlo usare più avanti in questo esercizio.

    Nota

    La stringa di connessione ha la sintassi seguente, in cui il segnaposto <server_name> rappresenta il nome del server identificato in precedenza in questa attività:

    psql "host=<server_name>.postgres.database.azure.com port=5432 dbname={your_database} user=student@<server_name> password={your_password} sslmode=require"
    
  8. Nel portale di Azure aprire una sessione Bash di Cloud Shell selezionando la relativa icona sulla barra degli strumenti accanto alla casella di testo della ricerca.

  9. All'interno della sessione Bash nel riquadro Cloud Shell incollare il valore della stringa di connessione psql dagli Appunti, modificarlo in modo che corrisponda al comando seguente ed eseguirlo per connettersi al database postgres ospitato nell'istanza del server appena distribuita di Database di Azure per PostgreSQL. Il valore del segnaposto <server_name> sarà già incluso nella stringa di connessione incollata dagli Appunti:

    psql "host=<server_name>.postgres.database.azure.com port=5432 dbname=postgres user=student@<server_name>.postgres.database.azure.com password=Pa55w0rd1234 sslmode=require"
    

    Nota

    Al termine della connessione, verrà visualizzato il prompt postgres=>.

Creare un database e tabelle di esempio

  1. Nel pannello Cloud Shell, eseguire il comando seguente dal prompt postgres=> per creare un nuovo database denominato cnamtinventory:

    CREATE DATABASE cnamtinventory;
    
  2. Eseguire il comando seguente per cambiare la connessione passando al database appena creato:

    \c cnamtinventory
    
  3. Eseguire il comando seguente per creare una tabella tenants:

    CREATE TABLE tenants (
      id bigserial PRIMARY KEY,
      name text NOT NULL,
      created_at TIMESTAMP DEFAULT NOW()::date,
      updated_at TIMESTAMP DEFAULT NOW()::date
    );
    
  4. Eseguire il comando seguente per creare una tabella inventory:

    CREATE TABLE inventory (
    id bigserial, 
    tenant_id bigint REFERENCES tenants (id),
    name VARCHAR(50),
    quantity INTEGER,
        date DATE NOT NULL DEFAULT NOW()::date,
        created_at TIMESTAMP DEFAULT NOW()::date,
        updated_at TIMESTAMP DEFAULT NOW()::date,
        PRIMARY KEY (tenant_id, id, date)
    ) PARTITION BY RANGE (date);
    
    CREATE TABLE inventory_default PARTITION OF inventory DEFAULT;
    

    Nota

    I dati vengono partizionati in base al valore della colonna date.

  5. Eseguire il comando seguente per verificare che la tabella sia stata creata correttamente:

    \dt
    
  6. Eseguire il comando seguente per caricare i dati di esempio nella tabella tenants:

    INSERT INTO tenants (id, name) VALUES (1, 'adatum');
    INSERT INTO tenants (id, name) VALUES (2, 'contoso');
    
  7. Eseguire il comando seguente per caricare i dati di esempio nella tabella inventory:

    INSERT INTO inventory (id, tenant_id, name, quantity) VALUES (1, 1, 'yogurt', 200);
    INSERT INTO inventory (id, tenant_id, name, quantity) VALUES (2, 1, 'milk', 100);
    INSERT INTO inventory (id, tenant_id, name, quantity) VALUES (1, 2, 'yogurt', 20);
    INSERT INTO inventory (id, tenant_id, name, quantity) VALUES (2, 2, 'milk', 10);
    
  8. Eseguire il comando seguente per verificare che la tabella inventory contenga i dati inseriti:

    SELECT * FROM inventory;
    
  9. Chiudere il riquadro Cloud Shell.

Integrare il server di Database di Azure per PostgreSQL con Microsoft Entra ID

Per integrare l'istanza del server di Database di Azure per PostgreSQL con Microsoft Entra ID, è necessario specificare un account utente di Microsoft Entra come amministratore di Active Directory designato del server. A questo scopo verrà usato l'account utente adatumadmin1 creato nell'attività precedente. È necessario accedere al server usando tale account utente. A questo punto, sarà possibile creare utenti di database basati su Microsoft Entra ID e assegnare loro ruoli del database. Si useranno gli oggetti di Microsoft Entra adatumuser1, adatumgroup1 e contosouser1 creati nell'esercizio precedente.

  1. All'interno della finestra del browser che visualizza il portale di Azure con il pannello del server di Database di Azure per PostgreSQL, selezionare Amministratore di Active Directory nella sezione Impostazioni nel menu verticale e quindi selezionare Imposta amministratore sulla barra degli strumenti.

  2. Nell'elenco degli account utente di Microsoft Entra nel riquadro Amministratore di Active Directory selezionare l'account utente adatumadmin1 creato nell'esercizio precedente, selezionare Seleziona e quindi selezionare Salva.

  3. Aprire un'altra finestra del Web browser in modalità in incognito/InPrivate, passare al portale di Azure e accedere usando l'account utente adatumadmin1 (con la password Pa55w.rd1234) creato nell'esercizio precedente.

  4. Nel portale di Azure aprire Cloud Shell selezionando la relativa icona sulla barra degli strumenti accanto alla casella di testo della ricerca.

  5. Quando viene richiesto di selezionare Bash o PowerShell, selezionare Bash e quindi, quando viene visualizzato il messaggio Non sono state montate risorse di archiviazione, selezionare Crea archivio.

  6. All'interno della sessione Bash nel riquadro Cloud Shell eseguire i comandi seguenti per recuperare e visualizzare un token di accesso di Microsoft Entra necessario per accedere a Database di Azure per PostgreSQL:

    FULL_TOKEN=$(az account get-access-token --resource-type oss-rdbms)
    echo $FULL_TOKEN
    

    Nota

    Il comando genera un output che include un token con codifica Base 64, che identifica l'utente autenticato nella risorsa Database di Azure per PostgreSQL.

    L'output usa il formato seguente:

    {
      "accessToken": "eyJ0eXAiOiJKV1QiLDJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL29zc3JkYm1zLWFhZC5kYXRhYmFzZS53aW5kb3dzLm5ldCIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0L2E2MTM5NTE0LTQxYTUtNDEyMy05ODFhLWVlN2JiOWU2YTNiNC8iLCJpYXQiOjE2MjE2MTc0NjUsIm5iZiI6MTYyMTYxNzQ2NSwiZXhwIjoxNjIxNjIxMzY0LCJhY3IiOiIxIiwiYWlvIjoiQVRRQXkvOFRBQUFBU1I5cXdVcm9KVVpmWEJabHY1NzRUenpmeGZFUlo1SXNDV3Z1aDVEOVBGWnZsL09SYWYzTGg3Zmx4NEFVaFpkVSIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiJiNjc3YzI5MC1jZjRiLTRhOGUtYTYwZS05MWJhNjUwYTRhYmUiLCJhcHBpZGFjciI6IjIiLCJpcGFkZHIiOiIxNDIuMTA1LjQ4LjUxIiwibmFtZSI6ImFkYXR1bWFkbWluMSIsIm9pZCI6Ijc2ZTdmYWI5LTZiOTItNGQzZi1hOGI5LWY1NWNhNDQyYzZiMSIsInB1aWQiOiIxMDAzMjAwMTQ0RTNDMDBBIiwicmgiOiIwLkFYd0FGSlVUcHFWQkkwR1lHdTU3dWVhanRKRENkN1pMejQ1S3BnNlJ1bVVLU3I1OEFNay4iLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJzdWIiOiJvNmhNMWlHXzM3MExaQk92UlpUQjBYeEdjSmpaOUVmN21lc1N2RkJYY3FFIiwidGlkIjoiYTYxMzk1MTQtNDFhNS00MTIzLTk4MWEtZWU3YmI5ZTZhM2I0IiwidW5pcXVlX25hbWUiOiJhZGF0dW1hZG1pbjFAbGl2ZWlkMjE3b3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1cG4iOiJhZGF0dW1hZG1pbjFAbGl2ZWlkMjE3b3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiJJdE81VndoU2lVV0o0UUZNQ04xQUFRIiwidmVyIjoiMS4wIn0.fFV3s2OjpVU52_SA8-atIDdkLN4onLgPmYrxa5eNCbuF0VbVOA5a9Ifv66H5a__6lMiLoV8n9EgTV4CpsLmvn6JFjAD9aHyEBkS2_iL_Rx-KCmlc7Vr6UHezrlrA3skf8oq3yb2Zqy_A3_kOrsnFgX8NP5uWoMmTzjWGTw3rOfjERJ7PowQC60nzlF1uCRDKIWw62SW4xiDQj23DSLDbkfUiG_Z9Swbw4DuMPTPeUVwz9AWhmg8lrqt5oawhKB-OMcpuwSf1-rE1cf2w54uthU6764DBEf5MVt8K95AKW0rey888znrIGKT-6yFenYUZZjL1aJ-jz8OIyNjuQK73XQ",
      "expiresOn": "2021-05-21 18:22:44.000000",
      "subscription": "d15bacf3-b17b-4ad5-a913-5fb904bd2f71",
      "tenant": "a6239514-41a5-4123-981a-ee7bb9e6a3b4",
      "tokenType": "Bearer"
    }
    
  7. Eseguire il comando seguente per impostare il valore della variabile PGPASSWORD sul valore del token di accesso dall'output del comando eseguito nel passaggio precedente:

    export PGPASSWORD=$(echo $FULL_TOKEN | jq -r '.accessToken')
    
  8. Eseguire il comando seguente per connettersi al database cnamtinventory usando lo strumento psql e usando l'autenticazione di Microsoft Entra (sostituire il segnaposto <server_name> con il nome del server identificato in precedenza in questo esercizio):

    DOMAIN_NAME=$(az rest --method GET --url 'https://management.azure.com/tenants?api-version=2020-01-01' --query "value[0].defaultDomain" -o tsv)
    psql "host=<server_name>.postgres.database.azure.com user=adatumadmin1@$DOMAIN_NAME@<server_name> dbname=cnamtinventory sslmode=require"
    

    Nota

    Dopo l'attivazione della connessione verrà visualizzato il prompt cnamtinventory=>.

  9. Dal prompt cnamtinventory=> eseguire il comando seguente per creare un ruolo del database corrispondente al gruppo di Microsoft Entra adatumgroup1 creato nell'esercizio precedente:

    CREATE ROLE "adatumgroup1" WITH LOGIN IN ROLE azure_ad_user;
    
  10. Eseguire il comando seguente per verificare che la creazione dei ruoli sia riuscita:

    SELECT rolname FROM pg_roles;
    
  11. Eseguire il comando seguente per concedere le autorizzazioni SELECT nella tabella inventory al gruppo adatumgroup1 creato nell'esercizio precedente:

    GRANT SELECT ON inventory TO adatumgroup1;
    
  12. Disconnettersi come account utente adatumadmin1 e chiudere la finestra del Web browser in modalità in incognito/InPrivate.

Registrare un'applicazione con Microsoft Entra ID

Per implementare un'applicazione basata su Node.js di esempio che usa l'autenticazione di Microsoft Entra per accedere a un database di Database di Azure per PostgreSQL, è necessario creare un oggetto applicazione di Microsoft Entra e l'entità di sicurezza corrispondente. In questo modo l'applicazione basata su Node.js potrà rappresentare gli utenti di Microsoft Entra al momento dell'accesso agli oggetti di database.

  1. Nel portale di Azure usare la casella di testo Cerca risorse, servizi e documenti per cercare Microsoft Entra ID e, nell'elenco dei risultati, selezionare Microsoft Entra ID.

  2. Nel riquadro Microsoft Entra selezionare Registrazioni app nella sezione Gestione nel menu verticale.

  3. Nel pannello Registrazioni app selezionare + Nuova registrazione.

  4. Nella casella di testo Nome nel pannello Registra un'applicazione immettere cna-app. Nella sezione Tipi di account supportati assicurarsi che sia selezionata l'opzione Account solo in questa directory dell'organizzazione (Solo directory predefinita - Tenant singolo). Nella sezione URI di reindirizzamento (facoltativo) impostare la voce Web su http://localhost:8080/redirect e quindi selezionare Registra.

    Screenshot of the Register an application blade in the Azure portal.

    Nota

    È possibile configurare il supporto multi-tenant per le applicazioni registrate di Microsoft Entra. Tuttavia, una presentazione dettagliata di questo approccio esula dagli scopi di questo modulo.

    Nota

    Dopo aver distribuito l'applicazione, sarà necessario modificare il valore URI di reindirizzamento (facoltativo) in modo che rifletta l'URL effettivo.

  5. Nel pannello cna-app esaminare le impostazioni risultanti e registrare i valori delle proprietà ID applicazione (client) e ID della directory (tenant).

    Screenshot of the cna-app blade in the Azure portal.

  6. Nella sezione Gestione del pannello cna-app selezionare Certificati e segreti e selezionare + Nuovo segreto client.

  7. Nella casella di testo Descrizione del pannello Aggiungi un segreto client immettere cna-secret-0. Lasciare il valore predefinito per l'elenco a discesa Scadenza e selezionare Aggiungi.

    Screenshot of the Add a client secret blade in the Azure portal.

  8. Tornare all'app can-app | Pannello Certificati e segreti , copiare il valore del segreto appena generato.

    Nota

    Assicurarsi di copiare il valore del segreto prima di uscire da questo pannello, perché in seguito non sarà più possibile recuperarlo. In questo caso, creare un altro segreto.

    Screenshot of the value of the client secret on the cna-app Certificates & secrets blade in the Azure portal.

  9. Nella can-app | Nel pannello Certificati e segreti, nel menu verticale, nella sezione Gestisci selezionare Autorizzazioni API.

    Screenshot of the cna-app API permissions blade in the Azure portal.

  10. Nel pannello cna-app | Autorizzazioni API selezionare +Aggiungi un'autorizzazione, nel pannello Richiedi le autorizzazioni dell'API selezionare la scheda API usate dall'organizzazione, nella casella di testo di ricerca immettere Azure OSSRDBMS Database (Database OSSRDBMS di Azure) e quindi nell'elenco dei risultati selezionare Azure OSSRDBMS Database.

    Screenshot of the Request API permissions blade in the Azure portal.

  11. Nel pannello Richiedi le autorizzazioni dell'API selezionare Autorizzazioni delegate, selezionare la casella di controllo user_impersonation e quindi selezionare Aggiungi autorizzazione.

    Screenshot of the Request API permissions blade in the Azure portal, with the Delegated permissions option selected.

  12. Di nuovo nel pannello cna-app | Autorizzazioni API selezionare Concedi consenso amministratore per Directory predefinita e, quando viene richiesta la conferma, selezionare .

    Screenshot of the cna-app API permissions blade in the Azure portal, with the prompt to confirm granting of the admin consent.

  13. Nel pannello cna-app | Autorizzazioni API verificare che le autorizzazioni siano state concesse.

    Screenshot of the cna-app API permissions blade in the Azure portal, with the consent and permissions granted.

Implementare un'applicazione semplice basata su Node.js integrata in Microsoft Entra

Dopo aver registrato l'applicazione nel tenant di Microsoft Entra, è ora possibile procedere con l'implementazione.

  1. Nel portale di Azure avviare una sessione Bash in Cloud Shell selezionando la relativa icona sulla barra degli strumenti accanto alla casella di testo della ricerca.

  2. All'interno della sessione Bash, nel riquadro Cloud Shell, eseguire i comandi seguenti per inizializzare un progetto Node.js in una nuova directory:

    mkdir -p cna-aadexpress && cd cna-aadexpress
    npm init -y
    
  3. Eseguire i comandi seguenti per aggiungere i pacchetti necessari alla dipendenza del progetto:

    npm install express
    npm install pg
    npm install @azure/msal-node
    
  4. Eseguire il comando seguente per creare un file denominato index.js nella radice del progetto:

    touch ./index.js
    
  5. Usare l'editor nano per aprire il file index.js e aggiungere il contenuto seguente. Più avanti in questa unità verrà creato un nome di app che sostituirà il segnaposto <webapp_name>. Sostituire <client_id>, <tenant_id>, <client_secret> e <server_name> (escluso il suffisso .postgres.database.azure.com) con i valori effettivi registrati in precedenza in questo esercizio:

    Nota

    I segnaposto <client_id> e <tenant_id> corrispondono alle proprietà ID applicazione (client) e ID della directory (tenant) a cui si è fatto riferimento in precedenza in questo esercizio.

    // Import dependencies
    const express = require("express");
    const msal = require('@azure/msal-node');
    const pg = require('pg');
    const port = process.env.PORT || 8080
    // Initialize express
    const app = express();
    app.use(express.json());
    app.listen(port, () => console.log(`Sample app is listening on port ${port}!`))
    
    // Authentication parameters
    const config = {
    auth: {
            clientId: "<client_id>",
            authority: "https://login.microsoftonline.com/<tenant_id>",
            clientSecret: "<client_secret>"
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
            console.log(message);
            },
        piiLoggingEnabled: false,
        logLevel: msal.LogLevel.Verbose,
        }
        }
    };
    
    var outputrows = ""
    
    // Initialize MSAL Node object using authentication parameters
    const cca = new msal.ConfidentialClientApplication(config);
    
    app.get('/auth', (req, res) => {
    
    redirectUri = req.hostname.toLowerCase()=="localhost" ? "http://localhost:8080/redirect" : "https://<webapp_name>.azurewebsites.net/redirect";
    
    // Construct a request object for auth code
    const authCodeUrlParameters = {
        scopes: ["https://ossrdbms-aad.database.windows.net/user_impersonation"],
        redirectUri: redirectUri,
    };
    
    // Request auth code, then redirect
    cca.getAuthCodeUrl(authCodeUrlParameters)
        .then((response) => {
            res.redirect(response);
        }).catch((error) => res.send(error));
    });
    
    app.get('/redirect', (req, res) => {
    redirectUri = req.hostname.toLowerCase()=="localhost" ? "http://localhost:8080/redirect" : "https://<webapp_name>.azurewebsites.net/redirect";
    
    // Use the auth code in redirect request to construct a token request object
    const tokenRequest = {
        code: req.query.code,
        scopes: ["https://ossrdbms-aad.database.windows.net/user_impersonation"],
        redirectUri: redirectUri,
    };
    
    // Exchange the auth code for tokens
    cca.acquireTokenByCode(tokenRequest)
    .then((response) => {
        //res.send(response);
    
        var username = 'adatumgroup1';
        var databasename = 'cnamtinventory';
        var servername = '<server_name>';
        var tablename = 'inventory';
    
        process.env.PGPASSWORD = response.accessToken;
        const connectionString =
            `postgres://${username}@${servername}@${servername}.postgres.database.azure.com:5432/${databasename}?ssl=true`;
    
        res.write(connectionString + "\n\n");
        res.write(response.accessToken + "\n\n");
    
        const client = new pg.Client(connectionString);
        client.connect(err => {
            if (err) throw err;
            else {
                queryDatabase(response.account.name);
            }
        });
    
        function queryDatabase(tenant_id) {
            console.log(`Running query to PostgreSQL server: ${servername}`);
            switch (tenant_id) {
                case "adatumuser1":
                    id = "1";
                    break;
                case "contosouser1":
                    id = "2";
                    break;
            }
            const query = `SELECT * FROM ${tablename} WHERE tenant_id = ${id};`;
            client.query(query)
            .then(qresponse => {
                const rows = qresponse.rows;
                rows.map(row => {
                    var singlerow = `${JSON.stringify(row)}`;
                    console.log(singlerow);
                    outputrows += singlerow + "\n";
                });
                res.write(outputrows);
                res.end();
                process.exit();
            })
            .catch(err => {
                 console.log(err);
            });
        }
      }).catch((error) => res.write(error));
    });
    

    Nota

    Un'applicazione registrata in Microsoft Entra multi-tenant usa l'URL dell'autorità generica authority: "https://login.microsoftonline.com/common", ma in questo caso è necessario specificare un URL di tenant singolo che includa l'ID del tenant in uso.

    Nota

    Tenere presente che, dopo aver distribuito l'applicazione, sarà necessario sostituire il valore URL DI REINDIRIZZAMENTO in modo che corrisponda all'URL di reindirizzamento effettivo.

  6. Usare l'editor nano per modificare il file package.json nella radice del progetto e sostituirlo con il contenuto seguente:

    {
      "name": "node-express",
      "version": "1.0.0",
      "description": "Node.js express sample",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "@azure/msal-node": "^1.1.0",
        "body-parser": "^1.19.0",
        "express": "^4.17.1",
        "http": "0.0.0",
        "morgan": "^1.10.0",
        "pg": "^8.6.0"
      }
    }
    

Convalidare la funzionalità dell'applicazione basata su Node.js

Si è infine pronti per testare la funzionalità dell'app Web. Sebbene sia possibile inserirla in un contenitore, per semplicità la distribuzione verrà eseguita in un servizio app di Azure. In questo modo sarà possibile convalidarne la funzionalità in modo rapido e assicurarsi che il relativo inserimento in contenitore sia un'opzione valida.

  1. Nel riquadro Cloud Shell della sessione Bash eseguire i comandi seguenti per creare un gruppo di risorse che ospiterà l'app Web di Azure, in cui si distribuirà l'app Node.js Express:

    RG1NAME=postgresql-db-RG
    LOCATION=$(az group show --resource-group $RG1NAME --query location --output tsv)
    RG2NAME=cna-aadexpress-RG
    az group create --name $RG2NAME --location $LOCATION
    
  2. Eseguire i comandi seguenti per creare un piano di servizio app di Azure gratuito che ospiterà la nuova app Web di Azure:

    SPNAME=aadexpress-sp
    az appservice plan create --name $SPNAME --resource-group $RG2NAME --sku F1 --is-linux
    
  3. Eseguire i comandi seguenti per creare la nuova app Web di Azure basata su Node.js:

    WEBAPPNAME=aadexpress$RANDOM$RANDOM
    az webapp create --name $WEBAPPNAME --resource-group $RG2NAME --plan $SPNAME --runtime "NODE|16-lts"
    
  4. Eseguire i comandi seguenti per identificare il nome dell'app Web:

    echo $WEBAPPNAME
    
  5. Usare l'editor nano per aprire il file index.js, sostituire i due segnaposto <webapp_name> con il nome identificato nel passaggio precedente, salvare le modifiche e chiudere il file.

    Nota

    Assicurarsi di sostituire entrambi i segnaposto <webapp_name>.

  6. Aprire un'altra scheda nella finestra del Web browser in cui è visualizzato il portale di Azure, passare al portale di Azure e, se richiesto, accedere alla sottoscrizione di Azure che verrà usata in questo modulo.

  7. Nel portale di Azure usare la casella di testo Cerca risorse, servizi e documenti per cercare Microsoft Entra ID e, nell'elenco dei risultati, selezionare Microsoft Entra ID.

  8. Nel riquadro Microsoft Entra passare al pannello Registrazioni app, selezionare la voce cna-app e selezionare Autenticazione nella sezione Gestione nel menu verticale.

  9. Nel pannello cna-app | Autenticazione modificare il valore di URI di reindirizzamento in modo che corrisponda alla voce aggiornata nel file index.js e salvare la modifica.

    Screenshot of the cna-app Authentication blade in the Azure portal.

  10. Tornare alla scheda del Web browser in cui è visualizzata la sessione Bash nel riquadro Cloud Shell ed eseguire i comandi seguenti per inizializzare il repository Git locale ed eseguire il commit di tutte le modifiche nel ramo principale:

    cd ~/cna-aadexpress
    git config --global user.email "user1@adatum.com"
    git config --global user.name "Adatum User1"
    git init
    git add -A
    git commit -m "Initial Commit"
    
  11. Eseguire i comandi seguenti per configurare le credenziali di distribuzione di livello utente:

    DEPLOYMENTUSER=m06User$RANDOM
    DEPLOYMENTPASS=m06Pass$RANDOM$RANDOM
    az webapp deployment user set --user-name $DEPLOYMENTUSER --password $DEPLOYMENTPASS
    
  12. Eseguire i comandi seguenti per identificare le credenziali di distribuzione di livello utente e registrarne il valore, perché saranno necessarie più avanti in questa attività:

    echo $DEPLOYMENTUSER
    echo $DEPLOYMENTPASS
    
  13. Eseguire i comandi seguenti per identificare l'URL di distribuzione dell'app Web di Azure che verrà usato come destinazione del comando git push:

    RG2NAME=cna-aadexpress-RG
    WEBAPPNAME=$(az webapp list --resource-group $RG2NAME --query "[0].name" --output tsv)
    DEPLOYMENTURL=$(az webapp deployment source config-local-git --name $WEBAPPNAME --resource-group $RG2NAME --output tsv)
    
  14. Eseguire il comando seguente per configurare il repository remoto denominato azure, che rappresenta l'URL di distribuzione identificato nel passaggio precedente:

    git remote add azure $DEPLOYMENTURL
    
  15. Eseguire i comandi seguenti per creare il ramo test in base al ramo main ed eseguirne il push del contenuto nell'app Web di Azure (quando viene richiesta la password che fa parte delle credenziali di distribuzione di livello utente registrate in precedenza in questa attività):

    git checkout -b test
    git commit -a -m "testing"
    git push --set-upstream azure test
    
  16. Chiudere il riquadro Cloud Shell.

  17. Aprire un'altra finestra del Web browser in modalità in incognito/InPrivate, passare al portale di Azure e accedere usando l'account utente adatumuser1 creato nell'esercizio precedente.

  18. Nel portale di Azure usare la casella di testo Cerca risorse, servizi e documentazione nella parte superiore della pagina del portale di Azure per cercare Servizi app.

  19. Nel pannello Servizi app, nell'elenco delle istanze del servizio app, selezionare la voce che rappresenta l'app Web di Azure appena distribuita.

  20. Nel pannello che visualizza le proprietà dell'app Web, nella sezione Informazioni di base copiare il valore dell'URL di Dominio predefinito.

  21. Aprire un'altra scheda nella stessa finestra del browser e nella casella di ricerca immettere https://, incollare l'URL appena copiato negli Appunti, aggiungere il suffisso /auth e quindi premere INVIO.

    Nota

    L'URL dovrà avere il formato seguente: https://<webapp_name>.azurewebsites.net/auth

  22. Verificare che la pagina Web risultante sia costituita dalle informazioni di autenticazione di Microsoft Entra per l'utente attualmente connesso (l'output potrebbe essere diverso).

    Screenshot of the page of the Node.js web app displaying the Microsoft Entra authentication information.

Risultati

Congratulazioni. Il secondo esercizio del modulo è stato completato. In questo esercizio è stato installato Database di Azure per PostgreSQL nel modello di distribuzione con server singolo, è stato creato un database con dati di inventario di esempio, il server è stato integrato in Microsoft Entra ID ed è stata implementata una semplice applicazione basata su Node.js che esegue query nel database usando l'autenticazione di Microsoft Entra.