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

时间:2018-03-22 09:17:57

标签: typescript azure-ad-b2c msal

当我通过loginRedirect登录时,我可以看到重定向上填充了MSAL令牌,但在尝试使用令牌时出现此错误:

  

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

     

AADB2C90077:用户没有现有会话,请求提示参数的值为'无'"通过连接到Azure B2C的Angular SPA应用程序成功登录后直接。

我在GitHub Issue中发现了类似内容,然后在由于没有令牌而被强制执行tokenPopup()后出现错误后,在another issue上发表了评论:

  

"此应用程序对此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;
  }
}

然后,一旦我登录,重定向就会重新定向,然后我会以角度重定向到另一条路线。该组件注入了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);
    });
  }
}

我的B2C作为连接Azure功能的邮递员应用程序,它绝对是B2C配置,我的代码或MSAL。 If it is我无法从B2C策略刀片修改这些设置,因此不确定他是如何解决的。

B2c配置列在1的评论中 我花了很多时间在这上面,这可能很容易,但是各个应用程序的多个范围以及范围刀片的不同问题和更改似乎比它应该更难

使用:

Angular: "5.2.0"
MSAL: "^0.1.5"

1 个答案:

答案 0 :(得分:0)

我有同样的错误。

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

<UserJourneyBehaviors>

<SessionExpiryType>Absolute</SessionExpiryType>

<SessionExpiryInSeconds>86400</SessionExpiryInSeconds>

</UserJourneyBehaviors>

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