1

我在一个连接到 MS Graph 的 MS Teams 应用程序上工作。我正在尝试在 MS Teams 中获取 MS Graph 的访问令牌。为了获得令牌,我正在使用 MSAL js。

如果我运行应用程序,gulp serve我会收到一个有效的令牌,并且我可以访问 MS Graph 端点。但是,如果我构建应用程序并将其安装在 MS Teams 中,userAgentApplication.acquireTokenSilent(config)则永远不会执行该功能。我在通话前后使用 console.log 对其进行了测试。没有抛出错误。

你知道为什么上面的代码片段没有在 MS Teams (app 和 webapp) 中执行吗?


新的:

在家里:

export function login() {
  const url = window.location.origin + '/login.html';

  microsoftTeams.authentication.authenticate({
    url: url,
    width: 600,
    height: 535,
    successCallback: function(result: string) {
      console.log('Login succeeded: ' + result);
      let data = localStorage.getItem(result) || '';
      localStorage.removeItem(result);

      let tokenResult = JSON.parse(data);
      storeToken(tokenResult.accessToken)
    },
    failureCallback: function(reason) {
      console.log('Login failed: ' + reason);
    }
  });
}

登录时

microsoftTeams.initialize();

    // Get the tab context, and use the information to navigate to Azure AD login page
    microsoftTeams.getContext(function (context) {
      // Generate random state string and store it, so we can verify it in the callback
      let state = _guid();
      localStorage.setItem("simple.state", state);
      localStorage.removeItem("simple.error");

      // See https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-implicit
      // for documentation on these query parameters
      let queryParams = {
        client_id: "XXX",
        response_type: "id_token token",
        response_mode: "fragment",
        scope: "https://graph.microsoft.com/User.Read openid",
        redirect_uri: window.location.origin + "/login-end.html",
        nonce: _guid(),
        state: state,
        login_hint: context.loginHint,
      };

      // Go to the AzureAD authorization endpoint (tenant-specific endpoint, not "common")
      // For guest users, we want an access token for the tenant we are currently in, not the home tenant of the guest. 
      let authorizeEndpoint = `https://login.microsoftonline.com/${context.tid}/oauth2/v2.0/authorize?` + toQueryString(queryParams);
      window.location.assign(authorizeEndpoint);
    });

    // Build query string from map of query parameter
    function toQueryString(queryParams) {
      let encodedQueryParams = [];
      for (let key in queryParams) {
        encodedQueryParams.push(key + "=" + encodeURIComponent(queryParams[key]));
      }
      return encodedQueryParams.join("&");
    }

    // Converts decimal to hex equivalent
    // (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
    function _decimalToHex(number) {
      var hex = number.toString(16);
      while (hex.length < 2) {
        hex = '0' + hex;
      }
      return hex;
    }

    // Generates RFC4122 version 4 guid (128 bits)
    // (From ADAL.js: https://github.com/AzureAD/azure-activedirectory-library-for-js/blob/dev/lib/adal.js)
    function _guid() {...}

在登录端

microsoftTeams.initialize();
    localStorage.removeItem("simple.error");
    let hashParams = getHashParameters();
    if (hashParams["error"]) {
      // Authentication/authorization failed
      localStorage.setItem("simple.error", JSON.stringify(hashParams));
      microsoftTeams.authentication.notifyFailure(hashParams["error"]);
    } else if (hashParams["access_token"]) {
      // Get the stored state parameter and compare with incoming state
      let expectedState = localStorage.getItem("simple.state");
      if (expectedState !== hashParams["state"]) {
        // State does not match, report error
        localStorage.setItem("simple.error", JSON.stringify(hashParams));
        microsoftTeams.authentication.notifyFailure("StateDoesNotMatch");
      } else {
        // Success -- return token information to the parent page.
        // Use localStorage to avoid passing the token via notifySuccess; instead we send the item key.
        let key = "simple.result";
        localStorage.setItem(key, JSON.stringify({
          idToken: hashParams["id_token"],
          accessToken: hashParams["access_token"],
          tokenType: hashParams["token_type"],
          expiresIn: hashParams["expires_in"]
        }));
        microsoftTeams.authentication.notifySuccess(key);
      }
    } else {
      // Unexpected condition: hash does not contain error or access_token parameter
      localStorage.setItem("simple.error", JSON.stringify(hashParams));
      microsoftTeams.authentication.notifyFailure("UnexpectedFailure");
    }
    // Parse hash parameters into key-value pairs
    function getHashParameters() {
      let hashParams = {};
      location.hash.substr(1).split("&").forEach(function (item) {
        let s = item.split("="),
          k = s[0],
          v = s[1] && decodeURIComponent(s[1]);
        hashParams[k] = v;
      });
      return hashParams;
    }
4

1 回答 1

1

尽管我的答案很晚,但我最近遇到了同样的问题。

解决方案非常简单:MSAL 静默登录在 MSTeams 中(目前)不起作用,因为 MSTeams 依赖于 MSAL 不支持的 IFrame 方法。

你可以在这个 Github Issue中阅读所有相关信息

幸运的是,他们即将在 Version 中发布对此的修复,msal 1.2.0并且已经有一个 npm-installable 测试版应该可以使它工作:

npm install msal@1.2.0-beta.2

更新:我自己试过这个 - 测试版也不能正常工作。微软在我自己的Github Issue中证实了这一点。

所以我想目前,您根本无法将 MSAL 用于 MS Teams。

于 2019-10-30T14:56:58.947 回答