简体   繁体   English

使用 Azure AD B2C 从 Angular 应用程序和 msal.js 登录重定向用户

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

I'm trying to get an Angular 4 app to correctly do an implicit authentication with Azure AD B2C.我正在尝试让 Angular 4 应用程序正确地使用 Azure AD B2C 进行隐式身份验证。 I'm using msal.js to try and make it to work.我正在使用 msal.js 来尝试使其工作。 I've checked the very limited official sample code , but it's of no real use as it's using a popup to login and I want to do a redirection.我检查了非常有限的官方示例代码,但它没有实际用处,因为它使用弹出窗口登录,我想做一个重定向。

What I have now is the following authentication service that I'm injecting in my app and that should take care of all the authentication.我现在拥有的是我在我的应用程序中注入的以下身份验证服务,它应该负责所有身份验证。

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();
    }
}

But it's not working.但它不起作用。 I get the ID token correctly, and it's valid, so the "Id token" does receive a value that I can use, but for a limited time.我正确地获得了 ID 令牌,并且它是有效的,因此“Id 令牌”确实收到了一个我可以使用的值,但在有限的时间内。

The issue is when I try to get the authentication token.问题是当我尝试获取身份验证令牌时。 The first call, to acquireTokenSilent returns an error that says : Token renewal operation failed due to timeout: null .第一次调用acquireTokenSilent返回一个错误,指出: Token renewal operation failed due to timeout: null

Then, I'm getting a popup that asks for a username and password, which, after a while disappears and I get an error that says User does not have an existing session and request prompt parameter has a value of 'None'.然后,我收到一个要求输入用户名和密码的弹出窗口,一段时间后消失,我收到一条错误消息,提示User does not have an existing session and request prompt parameter has a value of 'None'. . .

Edit:编辑:

So, I think I understand what's going on exactly and to reproduce the issue on a sample application that you can get here: https://github.com/Gimly/NetCoreAngularAzureB2CMsal所以,我想我明白到底发生了什么,并在您可以在这里获得的示例应用程序上重现该问题: https : //github.com/Gimly/NetCoreAngularAzureB2CMsal

If you connect from the homepage and then go to the fetchData page (the one with the weather forecast) you can see the auth token be correctly redeemed by acquireTokenSilent (open the browser console to get all the logs).如果您从主页连接,然后转到 fetchData 页面(有天气预报的页面),您可以看到acquireTokenSilent正确兑换了 auth 令牌(打开浏览器控制台以获取所有日志)。 But, if you refresh the page directly on fetchData, you can see the same behavior that I described, with acquireTokenSilent failing with the error about a timeout.但是,如果您直接在 fetchData 上刷新页面,您会看到我描述的相同行为, acquireTokenSilent失败并显示超时错误。

My best guess would be that, fore some reason, even though getUser returns a correct value, msal is not completely initialized before I call getAuthenticationToken and it's the reason for it to fail completely.我最好的猜测是,由于某种原因,即使getUser返回正确的值,在我调用getAuthenticationToken之前 msal 也没有完全初始化,这就是它完全失败的原因。

Now the real question... How do I make sure that it's completely initialized before trying to get the token?现在真正的问题是……在尝试获取令牌之前,我如何确保它已完全初始化?

OK, so the issue I was facing was caused by two things:好的,所以我面临的问题是由两件事引起的:

1) a bug in msal.js that caused the initialization process to not be fully completed at the end of the constructor call, and I was calling the acquireTokenSilent() before it had fully initialized. 1) msal.js 中的一个错误导致初始化过程在构造函数调用结束时没有完全完成,我在它完全初始化之前调用了acquireTokenSilent() This was fixed in the latest version (as of writing, still in the dev branch of the project).这在最新版本中得到了修复(在撰写本文时,仍在项目的 dev 分支中)。 See this GitHub issue for more info . 有关更多信息,请参阅此 GitHub 问题

2) I hadn't fixed the redirect URI, which caused the library to take the current URL as redirect URI which would fail because it wasn't in the list of allowed redirect URIs. 2)我没有修复重定向 URI,这导致库将当前 URL 作为重定向 URI,这会失败,因为它不在允许的重定向 URI 列表中。

After those two issues fixed, the code I posted in my question is working as expected.解决这两个问题后,我在问题中发布的代码按预期工作。

查看MSAL js 的源代码,您应该能够使用acquireTokenRedirect 而不是acquireTokenPopup。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular 8 与 Azure B2C 身份验证(使用 MSAL.js) - Angular 8 with Azure B2C Authentication (using MSAL.js) 使用B2C在Javascript / Angular 6 SPA应用程序中通过MSAL.JS注销的错误 - Error in Logout through MSAL.JS in Javascript / Angular 6 SPA application using B2C 来自 Angular 应用程序和 msal 的 Azure AD B2C:加载自定义 UI Html - Azure AD B2C from an Angular application and msal: Loading customized UI Html redirect_uri_mismatch Azure AD B2C,角度使用MSAL - redirect_uri_mismatch Azure AD B2C with angular using MSAL 登录到应用程序后,带有MSAL和Angular的Azure AD B2C会立即重定向到登录页面 - Azure AD B2C with MSAL and Angular redirects to login page immediately after logging into the app 登录的MSAL和AD B2C问题 - MSAL and AD B2C issues with login Azure Ad B2C:如何使用 msal-angular 传递在重定向中仍然可用的参数 url - Azure Ad B2C: How to use use msal-angular to pass parameter which still available in redirect url Azure B2C AD重定向到Angular应用程序 - Azure B2C AD Redirect to Angular App 使用Azure AD B2C时向Angular SPA和MSAL添加角色 - Adding roles to Angular SPA and MSAL when using using Azure AD B2C 在 NativeScript angular 应用程序中使用 Azure AD B2C 进行身份验证 - Authenticate using Azure AD B2C in a NativeScript angular Application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM