使用 Microsoft Graph 进行 firebase 身份验证 (accessToken)

Eri*_*ric 5 oauth access-token firebase firebase-authentication microsoft-graph-api

我非常希望有人能帮助我 - 我有点陷入困境。

我很高兴将 Firebase 身份验证与 Microsoft AD 结合使用。我的 AuthProvider 是firebase.auth.OAuthProvider('microsoft.com').

当我致电firebase.auth().signInWithPopup()该提供商时,一切都很好。accessToken我可以从结果中挑选出来UserCredential并访问 Microsoft Graph api 没有问题(耶!)。

Firebase 坚持并更新身份验证,当用户稍后返回我的 SPA 时,我的应用程序将通过onAuthStateChanged新的回调获得预期的回调(也耶!)。firebase.User

消息(我陷入困境)是:如何在此流程中获取 Microsoft GraphaccessToken(例如,当用户稍后返回我的应用程序时)?我不希望他们必须使用另一个弹出窗口重新进行身份验证(是的)。

基本上,当用户返回时,如何从有效的firebase.UserMS Graph 转变为 MS Graph ?accessToken

非常感谢您的帮助!

Eri*_*ric 3

更新/答案:所以事实证明比我想象的要简单:

基本思想是使用 firebase 进行身份验证(重新身份验证),并使用相同的 clientID进行静默 Microsoft 身份验证。但是,即使您之前已获得授权,您也必须loginHint 向 microsoft auth提供参数。loginHint 可以是 firebase 用户的电子邮件地址...

在这种情况下,身份验证是共享的,您不需要为该过程的“微软一半”弹出第二次登录 - firebase 身份验证工作正常。

我最终使用了微软的 MSAL 库(https://github.com/AzureAD/microsoft-authentication-library-for-js)...如下所示:

const graphDebug = false;
const msalLogger = new Logger(msalLogCallback, { level: LogLevel.Error });

export async function graphClient(loginHint: string) {
  const msal = new UserAgentApplication({
    // gotcha: MUST set the redirectUri, otherwise get weird errors when msal
    // tries to refresh an expired token.
    auth: { clientId: CLIENT_ID, redirectUri: window.location.origin },
    system: { logger: msalLogger },
    // TODO: should we set cache location to session/cookie?
  });

  /**
   * Create an authprovider for use in subsequent graph calls. Note that we use
   * the `aquireTokenSilent` mechanism which works because firebase has already
   * authenticated this user once, so we can share the single sign-on.
   *
   * In order for that to work, we must pass a `loginHint` with the user's
   * email. Failure to do that is fatal.
   */
  const authProvider: AuthProvider = callback => {
    msal
      .acquireTokenSilent({ scopes: SCOPES, loginHint })
      .then(result => {
        callback(null, result.accessToken);
      })
      .catch(err => callback(err, null));
  };

  const client = Client.init({
    authProvider,
    debugLogging: graphDebug,
  });

  return client;
}
Run Code Online (Sandbox Code Playgroud)