b2c msal 用户没有现有会话并请求提示参数

Clo*_*guy 5 typescript azure-ad-b2c azure-ad-msal

当我通过以下方式登录时loginRedirect我可以看到重定向上填充了 MSAL 令牌,但是当尝试使用该令牌时,我收到此错误:

无法以静默方式从存储中检索令牌。

AADB2C90077:用户没有现有会话,并且在通过连接到 Azure B2C 的 Angular SPA 应用成功登录后,请求提示参数的值为“无”。

我在GitHub Issue中发现了类似的内容,然后在由于没有令牌而被迫执行此操作后出现错误后对另一个问题进行了评论:tokenPopup()

“此应用程序没有足够的权限对​​此 Web 资源执行该操作”

他们可能没有关系,但他们都阻止了我

在此代码中,loginredirect可以工作,我可以在本地存储中看到令牌,然后下次使用令牌时,我会收到控制台日志,authCallback-err然后记录“无法从存储中静默检索令牌...”并首先提到错误。

@Injectable()
export class MsalService {
  private access_token: string;

  private tenantConfig = {
    tenant: environment.tenant,
    clientID: environment.clientID,
    signUpSignInPolicy: environment.signUpSignInPolicy,
    b2cScopes: environment.b2cScopes
  };

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

  private clientApplication: Msal.UserAgentApplication;

  private authCallback(errorDesc: any, token: any, error: any, tokenType: any) {
    var _this = this;
    console.log("authCallback");
    // For loginRedirect, tokenType = "id_token". For acquireTokenRedirect, tokenType:"access_token".
    if (token) {
      console.log("authCallback- Id token", token);
      this.access_token = token;
    } else {
      console.log("authCallback-err : " + error + ":" + errorDesc);
      alert("error here");
    }
  }

  constructor() {
    this.clientApplication = new Msal.UserAgentApplication(
      this.tenantConfig.clientID,
      this.authority,
      this.authCallback,
      {
        cacheLocation: "localStorage",
        redirectUri: "https://localhost:4200/msallogin"
      }
    );
  }

  get authenticated() {
    const user = this.clientApplication.getUser();
    if (user) {
      return true;
    }
    return false;
  }

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

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

  public login(): void {
    var _this = this;
    this.clientApplication.loginPopup(this.tenantConfig.b2cScopes).then(
      function(idToken: any) {
        _this.clientApplication
          .acquireTokenSilent(_this.tenantConfig.b2cScopes)
          .then(
            function(accessToken: any) {
              _this.access_token = accessToken;
              console.log("ACCESS TOKEN: \n " + _this.access_token);
            },
            function(error: any) {
              _this.clientApplication
                .acquireTokenPopup(_this.tenantConfig.b2cScopes)
                .then(
                  function(accessToken: any) {
                    _this.access_token = accessToken;
                  },
                  function(error: any) {
                    alert("Error acquiring the popup:\n" + error);
                  }
                );
            }
          );
      },
      function(error: any) {
        alert("Error during login:\n" + error);
      }
    );
  }

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

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

  public getUser(): string {
    const user = this.clientApplication.getUser();
    if (!user) {
      return null;
    }

    return user.name;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,一旦我登录,重定向就会回来,我会重定向到角度中的另一条路线。该组件已注入 MSAL 服务。

那时,我打电话getUser()就可以看到我的用户名。然后,我单击按钮发出 Web 请求,发出下一段代码作为拦截器,但由于没有令牌而失败

@Injectable() 导出类 MSALAuthenticationHttpInterceptor 实现 HttpInterceptor { 构造函数(private msalService: MsalService) {}

  @intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return Observable.fromPromise(
      this.msalService.getAuthenticationToken()
    ).switchMap(token => {
      req = req.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
      return next.handle(req);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我的 B2C 作为连接到 Azure 函数的邮递员应用程序运行,它肯定是 B2C 配置、我的代码或 MSAL。如果是我无法从 B2C 策略刀片修改这些设置,因此不确定他是如何解决的。

B2c配置在1的评论中列出 ,我在这方面花了很多时间,它可能很简单,但是由于跨不同应用程序的多个范围以及范围刀片的不同问题和更改,它似乎比应有的更难是

使用:

Angular: "5.2.0"
MSAL: "^0.1.5"
Run Code Online (Sandbox Code Playgroud)

小智 0

我有同样的错误。

我所做的就是在登录策略的 XML 文件中添加 2 行,这解决了我的问题。

<UserJourneyBehaviors>

<SessionExpiryType>Absolute</SessionExpiryType>

<SessionExpiryInSeconds>86400</SessionExpiryInSeconds>

</UserJourneyBehaviors>
Run Code Online (Sandbox Code Playgroud)

我希望它会有所帮助。:)