简体   繁体   中英

Use MSAL in Microsoft Teams not work JS

I work on an MS Teams app with a connection to MS Graph. I'm trying to get an access token for MS Graph in MS Teams. To get a token I'm using MSAL js.

If I run the App with gulp serve I receive a valid token and I have access to the MS Graph endpoints. But if I build the app and install it in MS Teams the function userAgentApplication.acquireTokenSilent(config) is never executed. I tested it with a console.log before and after the call. There is no error thrown.

Do you have any idea why the above snippet is not executed in MS Teams (app and webapp)?


NEW:

On Home:

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

On Login

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() {...}

on login end

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

Even though my answer is quite late, but I faced the same problem recently.

The solution is farely simple: MSALs silent login does not work in MSTeams (yet) as MSTeams relies on an IFrame Approach that is not supported by MSAL.

You can read all about it in this Github Issue

Fortunately, they are about to release a fix for this in Version msal 1.2.0 and there is already an npm-installable beta which should make this work:

npm install msal@1.2.0-beta.2

Update : I tried this myself - and the beta does not work as well. This was confirmed by Microsoft in my own Github Issue .

So I guess at the time being, you simply can't use MSAL for MS Teams.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM