簡體   English   中英

使用 Azure AD B2C 從 Angular 應用程序和 msal.js 登錄重定向用戶

[英]Login redirect a user with Azure AD B2C from an Angular application and msal.js

我正在嘗試讓 Angular 4 應用程序正確地使用 Azure AD B2C 進行隱式身份驗證。 我正在使用 msal.js 來嘗試使其工作。 我檢查了非常有限的官方示例代碼,但它沒有實際用處,因為它使用彈出窗口登錄,我想做一個重定向。

我現在擁有的是我在我的應用程序中注入的以下身份驗證服務,它應該負責所有身份驗證。

import { Injectable } from '@angular/core';
import * as Msal from 'msal';

@Injectable()
export class AuthenticationService {

    private tenantConfig = {
        tenant: "example.onmicrosoft.com",
        clientID: "redacted (guid of the client)",
        signUpSignInPolicy: "b2c_1_signup",
        b2cScopes: ["https://example.onmicrosoft.com/demo/read", "openid"]
    }

    private authority = "https://login.microsoftonline.com/tfp/" + this.tenantConfig.tenant + "/" + this.tenantConfig.signUpSignInPolicy;

    private clientApplication: Msal.UserAgentApplication;

    constructor() {
        this.clientApplication = new Msal.UserAgentApplication(this.tenantConfig.clientID, this.authority, this.authCallback);
    }

    public login(): void {
        this.clientApplication.loginRedirect(this.tenantConfig.b2cScopes);
    }

    public logout(): void {
        this.clientApplication.logout();
    }

    public isOnline(): boolean {
        return this.clientApplication.getUser() != null;
    }

    public getUser(): Msal.User {
        return this.clientApplication.getUser();
    }

    public getAuthenticationToken(): Promise<string> {
        return this.clientApplication.acquireTokenSilent(this.tenantConfig.b2cScopes)
            .then(token => {
                console.log("Got silent access token: ", token);
                return token;
            }).catch(error => {
                console.log("Could not silently retrieve token from storage.", error);
                return this.clientApplication.acquireTokenPopup(this.tenantConfig.b2cScopes)
                    .then(token => {
                        console.log("Got popup access token: ", token);
                        return token;
                    }).catch(error => {
                        console.log("Could not retrieve token from popup.", error);
                        this.clientApplication.acquireTokenRedirect(this.tenantConfig.b2cScopes);
                        return Promise.resolve("");
                    });
            });
    }

    private authCallback(errorDesc: any, token: any, error: any, tokenType: any) {
        console.log("Callback")

        if (token) {
            console.log("Id token", token);
        }
        else {
            console.log(error + ":" + errorDesc);
        }

        this.getAuthenticationToken();
    }
}

但它不起作用。 我正確地獲得了 ID 令牌,並且它是有效的,因此“Id 令牌”確實收到了一個我可以使用的值,但在有限的時間內。

問題是當我嘗試獲取身份驗證令牌時。 第一次調用acquireTokenSilent返回一個錯誤,指出: Token renewal operation failed due to timeout: null

然后,我收到一個要求輸入用戶名和密碼的彈出窗口,一段時間后消失,我收到一條錯誤消息,提示User does not have an existing session and request prompt parameter has a value of 'None'. .

編輯:

所以,我想我明白到底發生了什么,並在您可以在這里獲得的示例應用程序上重現該問題: https : //github.com/Gimly/NetCoreAngularAzureB2CMsal

如果您從主頁連接,然后轉到 fetchData 頁面(有天氣預報的頁面),您可以看到acquireTokenSilent正確兌換了 auth 令牌(打開瀏覽器控制台以獲取所有日志)。 但是,如果您直接在 fetchData 上刷新頁面,您會看到我描述的相同行為, acquireTokenSilent失敗並顯示超時錯誤。

我最好的猜測是,由於某種原因,即使getUser返回正確的值,在我調用getAuthenticationToken之前 msal 也沒有完全初始化,這就是它完全失敗的原因。

現在真正的問題是……在嘗試獲取令牌之前,我如何確保它已完全初始化?

好的,所以我面臨的問題是由兩件事引起的:

1) msal.js 中的一個錯誤導致初始化過程在構造函數調用結束時沒有完全完成,我在它完全初始化之前調用了acquireTokenSilent() 這在最新版本中得到了修復(在撰寫本文時,仍在項目的 dev 分支中)。 有關更多信息,請參閱此 GitHub 問題

2)我沒有修復重定向 URI,這導致庫將當前 URL 作為重定向 URI,這會失敗,因為它不在允許的重定向 URI 列表中。

解決這兩個問題后,我在問題中發布的代碼按預期工作。

查看MSAL js 的源代碼,您應該能夠使用acquireTokenRedirect 而不是acquireTokenPopup。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM