De pagina voor de omleidingsbridge instellen in MSAL Browser

Deze handleiding bevat frameworkspecifieke instructies voor het instellen van de omleidingsbrugpagina die is geïntroduceerd in MSAL Browser v5. Zie de migratiehandleiding v4 naar v5 voor achtergrondinformatie over waarom de omleidingsbrug nodig is.

Warning

De omleidingsbrugpagina mag niet worden geleverd met Cross-Origin-Opener-Policy headers. De brugpagina is een intermediair die het verificatieantwoord ontvangt nadat de IdP de OAuth-stroom heeft voltooid. Als COOP-headers zijn ingesteld op de brugpagina, voert de browser een wisseling van de browsecontextgroep uit, waardoor het communicatiekanaal met de hoofdtoepassing wordt verbroken en precies hetzelfde probleem opnieuw wordt geïntroduceerd dat de brug juist moet oplossen.

Important

Nadat u uw redirectUri hebt bijgewerkt zodat deze naar de nieuwe omleidingsbrugpagina verwijst, MOET u ook de redirect-URI bijwerken in uw app-registratie in Entra ID. De URI moet precies overeenkomen — inclusief pad, protocol en poort. Het niet bijwerken van de app-registratie leidt tot redirect_uri_mismatch fouten.

Angular

  1. Maak het omleidingsbrugonderdeel (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. Voeg de route toe aan uw /redirect routeringsconfiguratie. De omleidingsroute moet buiten de MsalGuard liggen, en de omleidingspagina mag geen API-aanroepen doen die MsalInterceptor zouden triggeren (of op een andere manier MSAL-API's aanroepen):
import { RedirectComponent } from "./redirect/redirect.component";

const routes: Routes = [
    { path: "redirect", component: RedirectComponent },
    // ... your other routes
];
  1. Zorg ervoor dat de build het onderdeel bevat. Er is geen angular.json wijziging van assets nodig wanneer u een Angular-routeonderdeel gebruikt. De Angular CLI bundelt het onderdeel automatisch. Als u liever een statisch redirect.html onderdeel gebruikt in plaats van een gerouteerd onderdeel, voegt u dit toe aan de assetsmatrix:
// angular.json
{
    "projects": {
        "your-app": {
            "architect": {
                "build": {
                    "options": {
                        "assets": [
                            { "glob": "**/*", "input": "public" },
                            "src/redirect.html" // ← Add redirect bridge page
                        ]
                    }
                }
            }
        }
    }
}

Voorbeeld: Zie angular-standalone-sample en angular-modules-sample.

Vite

Vite vereist een multipaginaconfiguratie zodat redirect.html als een afzonderlijk entry point in de buildoutput wordt opgenomen.

  1. Maak redirect.html in de hoofdmap van uw project (naast 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. Update vite.config.ts om de omleidingspagina toe te voegen als een tweede vermelding:
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
            },
        },
    },
});

Tijdens de ontwikkeling (vite dev) wordt de omleidingspagina automatisch aangeboden bij /redirect.html. In productieversies verzendt Rollup zowel index.html als redirect.html in de uitvoermap.

Voorbeeld: Zie het react-router-sample, typescript-sample en b2c-sample.

Webpack

Webpack vereist een speciaal toegangspunt en een HtmlWebpackPlugin exemplaar voor de omleidingspagina.

  1. Aanmaken 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. Aanmaken src/redirect.js (ingangspunt voor Webpack):
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

broadcastResponseToMainFrame().catch((error) => {
    console.error("Error broadcasting response:", error);
});
  1. Bijwerken 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

Omdat Next.js-pagina's automatisch routes worden, is de redirect-bridge een paginacomponent. De installatie verschilt tussen de paginarouter en de app-router.

Pages Router (pages/)

  1. Aanmaken 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. De omleidingspagina uitsluiten van 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. Maken app/redirect/page.js — dit moet een clientonderdeel zijn ("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. De omleidingsroute uitsluiten van MsalProvider in de hoofdindeling. Als je app/layout.js child-elementen in MsalProvider wikkelt, maak dan een aparte layout voor de redirectroute die dat overslaat:
// app/redirect/layout.js — no MsalProvider wrapper
export default function RedirectLayout({ children }) {
    return <>{children}</>;
}

Hiermee voorkomt u dat MSAL de hash van het authenticatieantwoord verwerkt voordat broadcastResponseToMainFrame() wordt uitgevoerd.


Er zijn geen next.config.js wijzigingen nodig voor geen van beide routers — Next.js serveert pagina's automatisch.

Voorbeeld: Zie nextjs-sample voor een voorbeeld van de Pages Router.

Express.js / Node.js-backend

Wanneer u Express.js (of een Node.js back-end met statische bestanden) gebruikt, configureert u de server om de omleidingspagina te bedienen zonder COOP-headers:

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")));

Voorbeeld: Zie de HybridSample.

Aanvullende bronnen