Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses Handbuch enthält frameworkspezifische Anweisungen zum Einrichten der Umleitungsbrückenseite, die in MSAL Browser v5 eingeführt wurde. Hintergrundinformationen dazu, warum die Umleitungsbrücke benötigt wird, finden Sie im v4 zu v5-Migrationshandbuch.
Warning
Die Redirect-Bridge-Seite darf NICHT mit Cross-Origin-Opener-Policy Headern ausgeliefert werden. Die Brückenseite ist ein Vermittler, der die Authentifizierungsantwort empfängt, nachdem der IdP den OAuth-Fluss abgeschlossen hat. Wenn auf der Brückenseite COOP-Header gesetzt sind, führt der Browser einen Wechsel der Browsing-Context-Gruppe durch, der den Kommunikationskanal zur Hauptanwendung trennt und damit genau das Problem wieder auftreten lässt, das die Brücke lösen soll.
Important
Nachdem Sie Ihre redirectUri so aktualisiert haben, dass sie auf die neue Redirect-Bridge-Seite verweist, MÜSSEN Sie auch die Redirect-URI in Ihrer Entra ID-App-Registrierung aktualisieren.
Der URI muss exakt übereinstimmen – einschließlich Pfad, Protokoll und Port.
Wenn die App-Registrierung nicht aktualisiert wird, führt dies zu redirect_uri_mismatch Fehlern.
Angular
-
Erstellen Sie die Umleitungsbrückenkomponente (
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);
});
}
}
-
Fügen Sie die
/redirectRoute in Ihrer Routingkonfiguration hinzu. Die Umleitungsroute muss sich außerhalb vonMsalGuardbefinden, und die Umleitungsseite sollte keine API-Aufrufe ausführen, dieMsalInterceptorauslösen würden (oder auf andere Weise MSAL-APIs aufrufen):
import { RedirectComponent } from "./redirect/redirect.component";
const routes: Routes = [
{ path: "redirect", component: RedirectComponent },
// ... your other routes
];
- Stellen Sie sicher, dass der Build die Komponente enthält. Bei Verwendung einer Angular-Route-Komponente ist keine
angular.jsonRessourcenänderung erforderlich – die Angular CLI bündelt die Komponente automatisch. Wenn Sie eine statischeredirect.htmlanstelle einer routingierten Komponente bevorzugen, fügen Sie sie dem Ressourcenarray hinzu:
// angular.json
{
"projects": {
"your-app": {
"architect": {
"build": {
"options": {
"assets": [
{ "glob": "**/*", "input": "public" },
"src/redirect.html" // ← Add redirect bridge page
]
}
}
}
}
}
}
Beispiel: Sehen Sie sich angular-standalone-sample und angular-modules-sample an.
Vite
Vite erfordert eine Multi-Page-Konfiguration, damit redirect.html als separater Einstiegspunkt in die Build-Ausgabe aufgenommen wird.
-
Erstellen Sie
redirect.htmlim Projektstammverzeichnis (nebenindex.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>
-
Aktualisieren
vite.config.ts, um die Weiterleitungsseite als zweiten Eintrag hinzuzufügen:
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
},
},
},
});
Während der Entwicklung (vite dev) wird die Umleitungsseite automatisch unter /redirect.html bereitgestellt. In Produktions-Builds erzeugt Rollup sowohl index.html als auch redirect.html im Ausgabeverzeichnis.
Beispiel: Sehen Sie sich das React-Router-Beispiel, typescript-sample und b2c-Sample an.
Webpack
Webpack erfordert einen dedizierten Einstiegspunkt und eine HtmlWebpackPlugin Instanz für die Umleitungsseite.
-
Erstellen
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>
-
Erstellen
src/redirect.js(Entry Point für Webpack):
import { broadcastResponseToMainFrame } from "@azure/msal-browser/redirect-bridge";
broadcastResponseToMainFrame().catch((error) => {
console.error("Error broadcasting response:", error);
});
-
Update
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 Seiten werden automatisch zu Routen, sodass die Umleitungsbrücke eine Seitenkomponente ist. Das Setup unterscheidet sich zwischen dem Pages Router und dem App-Router.
Pages Router (pages/)
-
Erstellen
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>;
}
-
Ausschließen der Umleitungsseite von
MsalProviderin_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/)
-
Erstellen
app/redirect/page.js— dies muss eine Clientkomponente sein ("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>;
}
-
Ausschließen der Umleitungsroute von
MsalProviderin Ihrem Stammlayout. Wenn Ihrapp/layout.jsuntergeordnete Elemente inMsalProvidereinbettet, erstellen Sie ein separates Layout für die Redirect-Route, das dies überspringt:
// app/redirect/layout.js — no MsalProvider wrapper
export default function RedirectLayout({ children }) {
return <>{children}</>;
}
Dadurch wird verhindert, dass MSAL den Hash der Authentifizierungsantwort verarbeitet, bevor broadcastResponseToMainFrame() ausgeführt wird.
Für beide Router sind keine next.config.js Änderungen erforderlich – Next.js stellt Seiten automatisch bereit.
Beispiel: Ein Beispiel für einen Pages Router finden Sie im nextjs-Beispiel .
Express.js / Node.js Backend
Wenn Sie Express.js verwenden (oder ein beliebiges Node.js-Backend, das statische Dateien ausliefert), konfigurieren Sie den Server so, dass er die Weiterleitungsseite ohne COOP-Header ausliefert:
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")));
Beispiel: Siehe "HybridSample".