JavaScript (MSAL.js) 用 Microsoft Authentication Library では非表示の iframe
要素を使用して、バックグラウンドでトークンが自動的に取得、更新されます。 Microsoft Entra ID によって、トークン要求で指定された登録済み redirect_uri
にトークンが戻されます (既定では、これはアプリのルート ページです)。 応答は 302 なので、結果は redirect_uri
にロードされる iframe
に対応する HTML になります。 通常、アプリの redirect_uri
はルート ページで、これにより、リロードされます。
他のケースでは、アプリのルートページへの移動に認証が必要な場合、入れ子状のiframe
要素やX-Frame-Options: deny
エラーが発生することがあります。
MSAL.js は Microsoft Entra ID によって発行された 302 を無視できず、返されたトークンを処理する必要があるため、 redirect_uri
が iframe
に読み込まれないようにすることはできません。
アプリ全体のリロードやこれにより発生するその他のエラーを回避するには、次の回避策に従ってください。
iframe に別の HTML を指定する
config の redirect_uri
プロパティを、認証を必要としない単純なページに設定します。 Microsoft Entra 管理センターに登録されている redirect_uri
と一致していることを確認する必要があります。 ユーザーがログイン プロセスを開始し、ログインが完了した後に正確な場所にリダイレクトされるときに、MSAL によってスタート ページが保存されるため、これはユーザーのログイン エクスペリエンスには影響しません。
メインのアプリケーションファイルで初期化を行う
アプリの初期化、ルーティングなどを定義する中央の単一 JavaScript ファイルが存在するようにアプリが構成されている場合、アプリが iframe
に読み込まれるかどうかに基づいてアプリ モジュールを条件付きで読み込むことができます。 例えば次が挙げられます。
AngularJS: app.js の場合
// Check that the window is an iframe and not popup
if (window !== window.parent && !window.opener) {
angular.module('todoApp', ['ui.router', 'MsalAngular'])
.config(['$httpProvider', 'msalAuthenticationServiceProvider','$locationProvider', function ($httpProvider, msalProvider,$locationProvider) {
msalProvider.init(
// msal configuration
);
$locationProvider.html5Mode(false).hashPrefix('');
}]);
}
else {
angular.module('todoApp', ['ui.router', 'MsalAngular'])
.config(['$stateProvider', '$httpProvider', 'msalAuthenticationServiceProvider', '$locationProvider', function ($stateProvider, $httpProvider, msalProvider, $locationProvider) {
$stateProvider.state("Home", {
url: '/Home',
controller: "homeCtrl",
templateUrl: "/App/Views/Home.html",
}).state("TodoList", {
url: '/TodoList',
controller: "todoListCtrl",
templateUrl: "/App/Views/TodoList.html",
requireLogin: true
})
$locationProvider.html5Mode(false).hashPrefix('');
msalProvider.init(
// msal configuration
);
}]);
}
Angular で: app.module.ts
// Imports...
@NgModule({
declarations: [
AppComponent,
MsalComponent,
MainMenuComponent,
AccountMenuComponent,
OsNavComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
MsalModule.forRoot(environment.MsalConfig),
SuiModule,
PagesModule
],
providers: [
HttpServiceHelper,
{provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true},
AuthService
],
entryComponents: [
AppComponent,
MsalComponent
]
})
export class AppModule {
constructor() {
console.log('APP Module Constructor!');
}
ngDoBootstrap(ref: ApplicationRef) {
if (window !== window.parent && !window.opener)
{
console.log("Bootstrap: MSAL");
ref.bootstrap(MsalComponent);
}
else
{
//this.router.resetConfig(RouterModule);
console.log("Bootstrap: App");
ref.bootstrap(AppComponent);
}
}
}
MsalComponent です。
import { Component} from '@angular/core';
import { MsalService } from '@azure/msal-angular';
// This component is used only to avoid Angular reload
// when doing acquireTokenSilent()
@Component({
selector: 'app-root',
template: '',
})
export class MsalComponent {
constructor(private Msal: MsalService) {
}
}
次のステップ
複数パートのチュートリアル シリーズで、ユーザーをサインインさせる React シングルページ アプリケーション (SPA) を構築して、さらに詳しく学習します。