Configurare l'autenticazione in un'applicazione a pagina singola di esempio usando Azure AD B2C

Questo articolo usa un'applicazione a pagina singola JavaScript di esempio per illustrare come aggiungere l'autenticazione di Azure Active Directory B2C (Azure AD B2C) ai contratti a pagina singola.

Panoramica

OpenID Connessione (OIDC) è un protocollo di autenticazione basato su OAuth 2.0. È possibile usarlo per accedere in modo sicuro a un utente in un'applicazione. Questo esempio di applicazione a pagina singola usa MSAL.js e il flusso PKCE OIDC. MSAL.js è una libreria fornita da Microsoft che semplifica l'aggiunta del supporto per l'autenticazione e l'autorizzazione ai contratti a pagina singola.

Flusso di accesso

Il flusso di accesso prevede i passaggi seguenti:

  1. Gli utenti passano all'app Web e seleziona Accedi.
  2. L'app avvia una richiesta di autenticazione e reindirizza gli utenti ad Azure AD B2C.
  3. Gli utenti si registrano o accedono e reimpostano la password. In alternativa, possono accedere con un account di social networking.
  4. Dopo l'accesso degli utenti, Azure AD B2C restituisce un codice di autorizzazione all'app.
  5. L'applicazione a pagina singola convalida il token ID, legge le attestazioni e a sua volta consente agli utenti di chiamare le risorse e le API protette.

Panoramica della registrazione dell'app

Per abilitare l'accesso dell'app con Azure AD B2C e chiamare un'API Web, registrare due applicazioni nella directory di Azure AD B2C.

  • La registrazione dell'applicazione Web consente all'app di accedere con Azure AD B2C. Durante la registrazione, si specifica l'URI di reindirizzamento. L'URI di reindirizzamento è l'endpoint a cui gli utenti vengono reindirizzati da Azure AD B2C dopo il completamento dell'autenticazione con Azure AD B2C. Il processo di registrazione dell'app genera un ID applicazione, noto anche come ID client, che identifica in modo univoco l'app.

  • La registrazione dell'API Web consente all'app di chiamare un'API Web sicura. La registrazione include gli ambiti dell'API Web. Gli ambiti consentono di gestire le autorizzazioni per le risorse protette, ad esempio l'API Web. Si concedono le autorizzazioni dell'applicazione Web agli ambiti dell'API Web. Quando viene richiesto un token di accesso, l'app specifica le autorizzazioni desiderate nel parametro di ambito della richiesta.

L'architettura e le registrazioni dell'app sono illustrate nel diagramma seguente:

Diagram of a web app with web API call registrations and tokens.

Chiamare a un'API Web

Al termine dell'autenticazione, gli utenti interagiscono con l'app, che richiama un'API Web protetta. L'API Web usa l'autenticazione del token di connessione. Il token di connessione è il token di accesso ottenuto dall'app da Azure AD B2C. L'app passa il token nell'intestazione di autorizzazione della richiesta HTTPS.

Authorization: Bearer <access token>

Se l'ambito del token di accesso non corrisponde agli ambiti dell'API Web, la libreria di autenticazione ottiene un nuovo token di accesso con gli ambiti corretti.

Disconnettersi

Il flusso di disconnesso prevede i passaggi seguenti:

  1. Dall'app gli utenti si disconnetteno.
  2. L'app cancella gli oggetti sessione e la libreria di autenticazione cancella la cache dei token.
  3. L'app porta gli utenti all'endpoint di disconnesso di Azure AD B2C per terminare la sessione di Azure AD B2C.
  4. Gli utenti vengono reindirizzati all'app.

Prerequisiti

Un computer che esegue:

Passaggio 1: Configurare il flusso utente

Quando gli utenti tentano di accedere all'app, l'app avvia una richiesta di autenticazione all'endpoint di autorizzazione tramite un flusso utente. Il flusso utente definisce e controlla l'esperienza utente. Dopo aver completato il flusso utente, Azure AD B2C genera un token e quindi reindirizza gli utenti all'applicazione.

Se non è già stato fatto, creare un flusso utente o un criterio personalizzato. Ripetere i passaggi per creare tre flussi utente separati come indicato di seguito:

  • Flusso utente di accesso e iscrizione combinato, ad esempio susi. Questo flusso utente supporta anche l'esperienza password dimenticata.
  • Flusso utente di modifica del profilo, ad esempio edit_profile.
  • Flusso utente di reimpostazione della password, ad esempio reset_password.

Azure AD B2C antepone B2C_1_ il nome del flusso utente. Ad esempio, susi diventa B2C_1_susi.

Passaggio 2: Registrare l'APPLICAZIONE a pagina singola e l'API

In questo passaggio si creano le registrazioni dell'applicazione a pagina singola e dell'API Web e si specificano gli ambiti dell'API Web.

Passaggio 2.1: Registrare l'applicazione API Web

Per creare la registrazione dell'app per le API Web (ID app: 2), seguire questa procedura:

  1. Accedi al portale di Azure.

  2. Assicurarsi di usare la directory che contiene il tenant di Azure AD B2C. Selezionare l'icona Directory e sottoscrizioni nella barra degli strumenti del portale.

  3. Nelle impostazioni del portale | Pagina Directory e sottoscrizioni , trovare la directory di Azure AD B2C nell'elenco Nome directory e quindi selezionare Cambia.

  4. Nel portale di Azure cercare e selezionare Azure AD B2C.

  5. Selezionare Registrazioni app e quindi Nuova registrazione.

  6. In Nome immettere un nome per l'applicazione, ad esempio my-api1. Lasciare i valori predefiniti per URI di reindirizzamento e Tipi di account supportati.

  7. Selezionare Registra.

  8. Al termine della registrazione dell'app, selezionare Panoramica.

  9. Registrare il valore ID applicazione (client) per usarlo in un secondo momento quando si configura l'applicazione Web.

    Screenshot that demonstrates how to get a web A P I application I D.

Passaggio 2.2: Configurare gli ambiti

  1. Selezionare l'applicazione my-api1 creata (ID app: 2) per aprire la relativa pagina Panoramica.

  2. In Gestisci selezionare Esponi un'API.

  3. Accanto a URI ID applicazione selezionare il collegamento Imposta. Sostituire il valore predefinito (GUID) con un nome univoco (ad esempio, tasks-api) e quindi selezionare Salva.

    Quando l'applicazione Web richiede un token di accesso per l'API Web, deve aggiungere questo URI come prefisso per ogni ambito definito per l'API.

  4. In Ambiti definiti da questa API selezionare Aggiungi un ambito.

  5. Per creare un ambito che definisce l'accesso in lettura all'API:

    1. In Nome ambito immettere tasks.read.
    2. Per Amministrazione nome visualizzato del consenso, immettere Accesso in lettura all'API attività.
    3. Per Amministrazione descrizione del consenso, immettere Consente l'accesso in lettura all'API delle attività.
  6. Seleziona Aggiungi ambito.

  7. Selezionare Aggiungi un ambito e quindi aggiungere un ambito che definisce l'accesso in scrittura all'API:

    1. In Nome ambito immettere tasks.write.
    2. Per Amministrazione nome visualizzato del consenso, immettere Accesso in scrittura all'API attività.
    3. Per Amministrazione descrizione del consenso, immettere Consenti l'accesso in scrittura all'API delle attività.
  8. Seleziona Aggiungi ambito.

Passaggio 2.3: Registrare l'applicazione a pagina singola

Per creare la registrazione a pagina singola, seguire questa procedura:

  1. Accedi al portale di Azure.
  2. Se si ha accesso a più tenant, selezionare l'icona Impostazioni nel menu in alto per passare al tenant di Azure AD B2C dal menu Directory e sottoscrizioni.
  3. Cerca e seleziona Azure AD B2C.
  4. Selezionare Registrazioni app e quindi Nuova registrazione.
  5. Immettere un nome per l'applicazione, ad esempio MyApp.
  6. Sotto Tipi di account supportati, seleziona Account in qualsiasi provider di identità o directory dell'organizzazione (per autenticare gli utenti con flussi utente).
  7. In URI di reindirizzamento selezionare Applicazione a pagina singola (SPA) e quindi, nella casella URL immettere http://localhost:6420.
  8. In Autorizzazioni selezionare la casella di controllo Concedi consenso amministratore a openid e autorizzazioni di accesso offline.
  9. Selezionare Registra.

Registrare l'ID applicazione (client) da usare in un secondo momento, quando si configura l'applicazione Web.

Screenshot of the web app Overview page for recording your web application ID.

Passaggio 2.4: Abilitare il flusso di concessione implicita

Nel proprio ambiente, se l'app SPA usa MSAL.js 1.3 o versioni precedenti e il flusso di concessione implicita o si configura l'app per il test di un flusso utente o criteri personalizzati, è necessario abilitare https://jwt.ms/ il flusso di concessione implicito nella registrazione dell'app:

  1. Nel menu a sinistra, in Gestisci, selezionare Autenticazione.

  2. In Flussi di concessione implicita e ibridi selezionare entrambe le caselle di controllo Token di accesso (usati per i flussi impliciti) e Token ID (usati per i flussi impliciti e ibridi).

  3. Seleziona Salva.

Se l'app usa MSAL.js 2.0 o versione successiva, non abilitare la concessione implicita del flusso come MSAL.js 2.0+ supporta il flusso del codice di autorizzazione con PKCE. L'app SPA in questo articolo usa il flusso PKCE e quindi non è necessario abilitare il flusso di concessione implicito.

Passaggio 2.5: Concedere le autorizzazioni

Per concedere all'app (ID app: 1) le autorizzazioni, seguire questa procedura:

  1. Selezionare Registrazioni app e quindi selezionare l'app creata (ID app: 1).

  2. In Gestisci selezionare Autorizzazioni API.

  3. In Autorizzazioni configurate selezionare Aggiungi un'autorizzazione.

  4. Selezionare la scheda Le mie API.

  5. Selezionare l'API (ID app: 2) a cui concedere l'accesso all'applicazione Web. Ad esempio, immettere my-api1.

  6. In Autorizzazione espandere le attività e quindi selezionare gli ambiti definiti in precedenza, ad esempio tasks.read e tasks.write.

  7. Selezionare Aggiungi autorizzazioni.

  8. Selezionare Concedi consenso amministratore per <il nome> del tenant.

  9. Selezionare .

  10. Selezionare Aggiorna e quindi verificare che Concesso per ... sia visualizzato in Stato per entrambi gli ambiti.

  11. Nell'elenco Autorizzazioni configurate selezionare l'ambito e quindi copiare il nome completo dell'ambito.

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

Passaggio 3: Ottenere il codice di esempio spa

Questo esempio illustra come un'applicazione a pagina singola può usare Azure AD B2C per l'iscrizione e l'accesso degli utenti. L'app acquisisce quindi un token di accesso e chiama un'API Web protetta.

Per ottenere il codice di esempio SPA, è possibile eseguire una delle operazioni seguenti:

  • Scaricare un file ZIP.

  • Clonare l'esempio da GitHub eseguendo il comando seguente:

    git clone https://github.com/Azure-Samples/ms-identity-b2c-javascript-spa.git
    

Passaggio 3.1: Aggiornare l'esempio di applicazione a pagina singola

Dopo aver ottenuto l'esempio spa, aggiornare il codice con i valori dell'API Web e di Azure AD B2C. Nella cartella di esempio aprire App i file JavaScript elencati nella tabella seguente e quindi aggiornarli con i valori corrispondenti.

file Chiave Valore
authConfig.js clientId ID spa del passaggio 2.3.
policies.js nomi I flussi utente o i criteri personalizzati creati nel passaggio 1.
policies.js Autorità I flussi utente di Azure AD B2C o le autorità di criteri personalizzati, https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<your-sign-in-sign-up-policy>ad esempio . Sostituire your-sign-in-sign-up-policy con il flusso utente o i criteri personalizzati creati nel passaggio 1
policies.js authorityDomain Dominio dell'autorità di Azure AD B2C, <your-tenant-name>.b2clogin.comad esempio .
apiConfig.js b2cScopes Ambiti dell'API Web creati nel passaggio 2.2 ,ad esempio b2cScopes: ["https://<your-tenant-name>.onmicrosoft.com/tasks-api/tasks.read"].
apiConfig.js webApi URL dell'API Web, http://localhost:5000/hello.

Il codice risultante dovrebbe essere simile all'esempio seguente:

authConfig.js:

const msalConfig = {
    auth: {
      clientId: "<your-MyApp-application-ID>", // This is the ONLY mandatory field; everything else is optional.
      authority: b2cPolicies.authorities.signUpSignIn.authority, // Choose sign-up/sign-in user-flow as your default.
      knownAuthorities: [b2cPolicies.authorityDomain], // You must identify your tenant's domain as a known authority.
      redirectUri: "http://localhost:6420", // You must register this URI on Azure Portal/App Registration. Defaults to "window.location.href".
    },
    cache: {
      cacheLocation: "sessionStorage",  
      storeAuthStateInCookie: false, 
    },
    system: {
      loggerOptions: {
        loggerCallback: (level, message, containsPii) => {
          if (containsPii) {
            return;
          }
          switch (level) {
            case msal.LogLevel.Error:
              console.error(message);
              return;
            case msal.LogLevel.Info:
              console.info(message);
              return;
            case msal.LogLevel.Verbose:
              console.debug(message);
              return;
            case msal.LogLevel.Warning:
              console.warn(message);
              return;
          }
        }
      }
    }
  };
};

const loginRequest = {
  scopes: ["openid", ...apiConfig.b2cScopes],
};

const tokenRequest = {
  scopes: [...apiConfig.b2cScopes],  // e.g. ["https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"]
  forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

policies.js:

const b2cPolicies = {
    names: {
        signUpSignIn: "b2c_1_susi",
        forgotPassword: "b2c_1_reset",
        editProfile: "b2c_1_edit_profile"
    },
    authorities: {
        signUpSignIn: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi",
        },
        forgotPassword: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_reset",
        },
        editProfile: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile"
        }
    },
    authorityDomain: "your-tenant-name.b2clogin.com"
}

apiConfig.js:

const apiConfig = {
  b2cScopes: ["https://your-tenant-name.onmicrosoft.com/tasks-api/tasks.read"],
  webApi: "http://localhost:5000/hello"
};

Passaggio 4: Ottenere il codice di esempio dell'API Web

Dopo aver registrato l'API Web e aver definito i relativi ambiti, configurare il codice dell'API Web per l'uso con il tenant di Azure AD B2C.

Per ottenere il codice di esempio dell'API Web, eseguire una delle operazioni seguenti:

Passaggio 4.1: Aggiornare l'API Web

  1. Aprire il file config.json nell'editor di codice.

  2. Modificare i valori delle variabili con la registrazione dell'applicazione creata in precedenza. Aggiornare con policyName il flusso utente creato come parte dei prerequisiti (ad esempio, b2c_1_susi).

    "credentials": {
        "tenantName": "<your-tenant-name>",
        "clientID": "<your-webapi-application-ID>"
    },
    "policies": {
        "policyName": "b2c_1_susi"
    },
    "resource": {
        "scope": ["tasks.read"] 
    },
    

Passaggio 4.2: Abilitare CORS

Per consentire all'applicazione a pagina singola di chiamare l'API Web Node.js, è necessario abilitare la condivisione di risorse tra le origini (CORS) nell'API Web. In un'applicazione di produzione prestare attenzione al dominio che effettua la richiesta. In questo esempio consentire le richieste da qualsiasi dominio.

Per abilitare CORS, usare il middleware seguente. Nell'esempio di codice dell'API Web Node.js scaricato è già stato aggiunto al file index.js .

app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Passaggio 5: Eseguire l'APPLICAZIONE a pagina singola e l'API Web

A questo punto si è pronti per testare l'accesso con ambito dell'applicazione a pagina singola all'API. Eseguire sia l'API Web Node.js che l'applicazione a pagina singola JavaScript nel computer locale. Accedere quindi all'applicazione a pagina singola e fare clic sul pulsante per Chiamata di API per avviare una richiesta all'API protetta.

Eseguire l'API Web Node.js:

  1. Aprire una finestra della console e passare alla directory che contiene l'esempio di API Web Node.js. Ad esempio:

    cd active-directory-b2c-javascript-nodejs-webapi
    
  2. Eseguire i comandi seguenti:

    npm install && npm update
    node index.js
    

    Nella finestra della console viene visualizzato il numero della porta in cui è ospitata l'applicazione.

    Listening on port 5000...
    

Eseguire l'app a pagina singola

  1. Aprire un'altra finestra della console e passare alla directory che contiene l'esempio spa JavaScript. Ad esempio:

    cd ms-identity-b2c-javascript-spa
    
  2. Eseguire i comandi seguenti:

    npm install && npm update
    npm start
    

    Nella finestra della console viene visualizzato il numero della porta in cui è ospitata l'applicazione.

    Listening on port 6420...
    
  3. Per visualizzare l'applicazione, passare a http://localhost:6420 nel browser.

    Screenshot of the SPA sample app displayed in the browser window.

  4. Completare il processo di iscrizione o accesso. Dopo aver eseguito l'accesso, verrà visualizzato il messaggio "User your username logged in" (Utente <connesso al nome utente> ).

  5. Selezionare il pulsante Call API (Chiama API). L'applicazione a pagina singola invia il token di accesso in una richiesta all'API Web protetta, che restituisce il nome visualizzato dell'utente connesso:

    Screenshot of the SPA in a browser window, showing the username JSON result that's returned by the API.

Distribuire l'applicazione

In un'applicazione di produzione, l'URI di reindirizzamento della registrazione dell'app è in genere un endpoint accessibile pubblicamente in cui l'app è in esecuzione, ad esempio https://contoso.com/signin-oidc.

È possibile aggiungere e modificare gli URI di reindirizzamento nelle applicazioni registrate in qualsiasi momento. Agli URL di reindirizzamento si applicano le restrizioni seguenti:

  • L'URL di risposta deve iniziare con lo schema https.
  • L'URL di risposta rileva la distinzione tra maiuscole e minuscole. Le maiuscole e le minuscole devono corrispondere a quelle nel percorso URL dell'applicazione in esecuzione.

Passaggi successivi

Per altre informazioni sui concetti illustrati in questo articolo: