代码之家  ›  专栏  ›  技术社区  ›  Gimly

登录从Angular应用程序和msal重定向使用Azure AD B2C的用户。js公司

  •  8
  • Gimly  · 技术社区  · 8 年前

    我正在尝试让Angular 4应用程序正确地使用Azure AD B2C进行隐式身份验证。我正在使用msal。js尝试并使其生效。我检查了非常有限的 official sample code ,但它没有真正的用途,因为它使用弹出菜单登录,我想做一个重定向。

    我现在拥有的是以下身份验证服务,我正在我的应用程序中注入该服务,它应该负责所有的身份验证。

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

    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页面(带有天气预报的页面),您可以看到auth令牌由正确兑换 (打开浏览器控制台以获取所有日志)。但是,如果您直接在fetchData上刷新页面,您可以看到与我描述的相同的行为,包括 acquireTokenSilent获取令牌 失败,出现超时错误。

    我最好的猜测是,出于某种原因,即使 getUser 返回正确的值,msal在调用之前未完全初始化 getAuthenticationToken 这也是它彻底失败的原因。

    现在真正的问题是。。。在尝试获取令牌之前,如何确保它已完全初始化?

    2 回复  |  直到 5 年前
        1
  •  3
  •   Gimly    8 年前

    好的,所以我面临的问题是由两件事引起的:

    1) msal中的错误。js导致初始化过程在构造函数调用结束时没有完全完成,我正在调用 acquireTokenSilent() 在它完全初始化之前。这在最新版本中得到了修复(截至编写时,仍在项目的开发分支中)。 See this GitHub issue for more info .

    2) 我没有修复重定向URI,这导致库将当前URL作为重定向URI,这将失败,因为它不在允许的重定向URI列表中。

    在这两个问题解决后,我在问题中发布的代码按预期工作。

        2
  •  0
  •   Parakh    8 年前

    查看 source code 对于MSAL js,您应该能够使用acquireTokenRedirect而不是acquireTokenPopup。