Nastavení stránky mostu přesměrování v prohlížeči MSAL

Tato příručka obsahuje pokyny specifické pro architekturu pro nastavení stránky mostu přesměrování představené v prohlížeči MSAL v5. Základní informace o tom, proč je potřeba přesměrovat most, najdete v průvodci migrací z verze 4 na verzi 5.

Warning

Stránka přesměrovacího mostu nesmí být doručována s hlavičkami Cross-Origin-Opener-Policy. Přemosťovací stránka je mezivrstva, která přijímá ověřovací odpověď poté, co zprostředkovatel identity (IdP) dokončí tok OAuth. Pokud jsou na přemosťovací stránce nastaveny hlavičky COOP, prohlížeč provede výměnu skupiny kontextu procházení, čímž se přeruší komunikační kanál s hlavní aplikací — a znovu tím vznikne přesně ten problém, který má most řešit.

Important

Po aktualizaci redirectUri na novou stránku mostu přesměrování musíte aktualizovat také identifikátor URI přesměrování v registraci aplikace Entra ID. Identifikátor URI se musí přesně shodovat – včetně cesty, protokolu a portu. Neaktualizování registrace aplikace povede k chybám redirect_uri_mismatch.

Angular

  1. Vytvoření komponenty přesměrového mostu (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. Přidejte trasu /redirect do konfigurace směrování. Cesta přesměrování musí být mimoMsalGuard a stránka přesměrování by neměla volat rozhraní API, která by aktivovala MsalInterceptor (nebo jinak volala rozhraní MSAL API):
import { RedirectComponent } from "./redirect/redirect.component";

const routes: Routes = [
    { path: "redirect", component: RedirectComponent },
    // ... your other routes
];
  1. Ujistěte se, že sestavení obsahuje komponentu. Při použití komponenty trasy v Angularu není nutná žádná změna angular.json assetů — Angular CLI tuto komponentu automaticky zahrne do bundlu. Pokud dáváte přednost statické redirect.html místo komponenty se směrováním, přidejte ji do pole assets:
// angular.json
{
    "projects": {
        "your-app": {
            "architect": {
                "build": {
                    "options": {
                        "assets": [
                            { "glob": "**/*", "input": "public" },
                            "src/redirect.html" // ← Add redirect bridge page
                        ]
                    }
                }
            }
        }
    }
}

Ukázka: Viz angular-standalone-sample a angular-modules-sample.

Vite

Vite vyžaduje vícestránkovou konfiguraci, aby redirect.html byla zahrnuta jako samostatný vstupní bod ve výstupu sestavení.

  1. Vytvořte redirect.html v kořenovém adresáři projektu (vedle 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. Aktualizace vite.config.ts pro přidání stránky pro přesměrování jako druhou položku:
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
            },
        },
    },
});

Během vývoje (vite dev) je stránka přesměrování automaticky dostupná na adrese /redirect.html. Při produkčním sestavení Rollup vygeneruje ve výstupním adresáři jak index.html, tak redirect.html.

Ukázka: Viz ukázka react-router-sample, typescript-sample a b2c-sample.

Webpack

Webpack vyžaduje vyhrazený vstupní bod a HtmlWebpackPlugin instanci pro stránku přesměrování.

  1. Vytvořit 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. Vytvořit src/redirect.js (vstupní bod pro Webpack):
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";

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

Next.js stránky se automaticky stanou trasami, takže most pro přesměrování je součást stránky. Nastavení se liší mezi směrovačem stránek a směrovačem aplikací.

Směrovač stránek (pages/)

  1. Vytvořit 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. Vylučte stránku přesměrování z MsalProvider v _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>
    );
}

Směrovač aplikací (app/)

  1. Vytvořit app/redirect/page.js — musí se jednat o klientskou komponentu ("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. Vylučte trasu přesměrování z MsalProvider v kořenovém rozvržení. Pokud vaše app/layout.js obaluje podřízené prvky do MsalProvider, vytvořte pro přesměrovací trasu samostatný layout, který ho přeskočí:
// app/redirect/layout.js — no MsalProvider wrapper
export default function RedirectLayout({ children }) {
    return <>{children}</>;
}

Tím se zabrání tomu, aby MSAL zpracoval hash ověřovací odpovědi před spuštěním broadcastResponseToMainFrame().


U žádného z routerů nejsou potřeba žádné next.config.js změny – Next.js stránky obsluhuje automaticky.

Ukázka: Příklad směrovače Pages najdete v nextjs-sample.

back-end Express.js / Node.js

Pokud používáte Express.js (nebo jakýkoli Node.js back-end obsluhující statické soubory), nakonfigurujte server tak, aby obsluhovat stránku přesměrování bez hlaviček 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")));

Ukázka: Podívejte se na hybridSample.

Další zdroje