Configurare la pagina bridge per il reindirizzamento in MSAL Browser

Questa guida fornisce istruzioni specifiche del framework per la configurazione della pagina del bridge di reindirizzamento introdotta in MSAL Browser v5. Per informazioni sul motivo per cui è necessario il bridge di reindirizzamento, vedere la guida alla migrazione da v4 a v5.

Avvertimento

La pagina ponte di reindirizzamento NON deve essere servita senza Cross-Origin-Opener-Policy intestazioni. La pagina ponte funge da intermediario e riceve la risposta di autenticazione dopo il completamento del flusso OAuth da parte dell'IdP. Se nella pagina bridge sono impostate intestazioni COOP, il browser esegue una sostituzione del gruppo di contesto di navigazione che interrompe il canale di comunicazione con l'applicazione principale, reintroducendo proprio il problema che il bridge è progettato per risolvere.

Importante

Dopo aver aggiornato redirectUri in modo che punti alla nuova pagina del bridge di reindirizzamento, DEVI anche aggiornare l'URI di reindirizzamento nella registrazione dell'app di Entra ID. L'URI deve corrispondere esattamente , inclusi percorso, protocollo e porta. Il mancato aggiornamento della registrazione dell'app comporterà errori redirect_uri_mismatch.

Angular

  1. Crea il componente ponte di reindirizzamento (src/app/redirect/redirect.component.ts):
import { Component, OnInit } from "@angular/core";
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

@Component({
    selector: "app-redirect",
    standalone: true,
    template: "<p>Processing authentication...</p>",
})
export class RedirectComponent implements OnInit {
    ngOnInit(): void {
        broadcastResponseToMainFrame().catch((error: Error) => {
            console.error("Error broadcasting response to main frame:", error);
        });
    }
}
  1. Aggiungere la /redirect route nella configurazione di routing. La route di reindirizzamento deve essere esterna aMsalGuarde la pagina di reindirizzamento non deve effettuare chiamate API che attiverebbero MsalInterceptor (o altrimenti richiamano le API MSAL):
import { RedirectComponent } from "./redirect/redirect.component";

const routes: Routes = [
    { path: "redirect", component: RedirectComponent },
    // ... your other routes
];
  1. Verificare che la compilazione includa il componente. Non è necessaria alcuna angular.json modifica degli asset quando si usa un componente di routing di Angular: Angular CLI include automaticamente il componente nel bundle. Se si preferisce un componente statico redirect.html anziché un componente indirizzato, aggiungerlo alla matrice assets:
// angular.json
{
    "projects": {
        "your-app": {
            "architect": {
                "build": {
                    "options": {
                        "assets": [
                            { "glob": "**/*", "input": "public" },
                            "src/redirect.html" // ← Add redirect bridge page
                        ]
                    }
                }
            }
        }
    }
}

Esempio: Vedere angular-standalone-sample e angular-modules-sample.

Vite

Vite richiede una configurazione a più pagine in modo che redirect.html sia inclusa come punto di ingresso separato nell'output di compilazione.

  1. Creare redirect.html nella radice del progetto (accanto a index.html):
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Redirect</title>
</head>
<body>
    <p>Processing authentication...</p>
    <script type="module">
        import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

        broadcastResponseToMainFrame().catch((error) => {
            console.error("Error broadcasting response:", error);
        });
    </script>
</body>
</html>
  1. Aggiorna vite.config.ts per aggiungere la pagina di reindirizzamento come seconda voce:
import { defineConfig } from "vite";
import { resolve } from "path";

export default defineConfig({
    build: {
        rollupOptions: {
            input: {
                main: resolve(__dirname, "index.html"),
                redirect: resolve(__dirname, "redirect.html"), // ← Redirect bridge entry
            },
        },
    },
});

Durante lo sviluppo (vite dev), la pagina di reindirizzamento viene gestita automaticamente in /redirect.html. Nelle build di produzione, Rollup produce sia index.html che redirect.html nella directory di output.

Esempio: Vedere react-router-sample, typescript-sample e b2c-sample.

Webpack

Webpack richiede un punto di ingresso dedicato e un'istanza HtmlWebpackPlugin per la pagina di reindirizzamento.

  1. Creare src/redirect.html:
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Redirect</title>
</head>
<body>
    <p>Processing authentication...</p>
    <!-- The redirect script bundle will be injected by HtmlWebpackPlugin (see redirect.js entry). -->
</body>
</html>
  1. Creare src/redirect.js (punto di ingresso per Webpack):
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

broadcastResponseToMainFrame().catch((error) => {
    console.error("Error broadcasting response:", error);
});
  1. Aggiornare webpack.config.js:
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: {
        main: "./src/index.js",
        redirect: "./src/redirect.js", // ← Redirect bridge entry
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: "index.html",
            template: "./src/index.html",
            chunks: ["main"],
        }),
        new HtmlWebpackPlugin({
            filename: "redirect.html",
            template: "./src/redirect.html",
            chunks: ["redirect"], // ← Only include the redirect chunk
        }),
    ],
};

Next.js

Le pagine di Next.js diventano automaticamente route, quindi il ponte di reindirizzamento è un componente di pagina. La configurazione è diversa tra il router Pages e il router dell'app.

Router delle pagine (pages/)

  1. Creare pages/redirect.js:
import { useEffect } from "react";
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

export default function Redirect() {
    useEffect(() => {
        broadcastResponseToMainFrame().catch((error) => {
            console.error("Error broadcasting response to main frame:", error);
        });
    }, []);

    return <p>Processing authentication...</p>;
}
  1. Escludere la pagina di reindirizzamento da MsalProvider in _app.js:
// pages/_app.js
import { useRouter } from "next/router";
import { MsalProvider } from "@azure/msal-react";

function MyApp({ Component, pageProps }) {
    const router = useRouter();

    // The redirect page must NOT be wrapped in MsalProvider
    if (router.pathname === "/redirect") {
        return <Component {...pageProps} />;
    }

    return (
        <MsalProvider instance={msalInstance}>
            <Component {...pageProps} />
        </MsalProvider>
    );
}

App Router (app/)

  1. Creare app/redirect/page.js — deve essere un componente client ("use client"):
"use client";

import { useEffect } from "react";
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

export default function Redirect() {
    useEffect(() => {
        broadcastResponseToMainFrame().catch((error) => {
            console.error("Error broadcasting response to main frame:", error);
        });
    }, []);

    return <p>Processing authentication...</p>;
}
  1. Escludi il percorso di reindirizzamento da MsalProvider dal layout radice. Se il tuo app/layout.js racchiude i componenti figli in MsalProvider, crea un layout separato per il percorso di reindirizzamento che lo salti:
// app/redirect/layout.js — no MsalProvider wrapper
export default function RedirectLayout({ children }) {
    return <>{children}</>;
}

Ciò impedisce a MSAL di elaborare l'hash della risposta di autenticazione prima che broadcastResponseToMainFrame() venga eseguito.


Non next.config.js sono necessarie modifiche per entrambi i router: Next.js serve automaticamente le pagine.

Esempio: Vedere l'esempio nextjs-sample per un esempio di Router Pages.

Backend Express.js / Node.js

Quando si utilizza Express.js (o qualsiasi Node.js back-end che gestisce file statici), configurare il server per gestire la pagina di reindirizzamento senza intestazioni COOP:

const express = require("express");
const path = require("path");
const app = express();

// Serve the redirect bridge page WITHOUT COOP headers
app.get("/redirect", (req, res) => {
    res.sendFile(path.join(__dirname, "public", "redirect.html"));
});

// Set COOP headers for all other routes
app.use((req, res, next) => {
    res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
    next();
});

app.use(express.static(path.join(__dirname, "public")));

Esempio: Vedere HybridSample.

Risorse aggiuntive