首页 文章

非管理员的Microsoft Graph API权限?

提问于
浏览
1

我正在尝试与Office365租户中的所有用户创建一个下拉列表 . 我在Azure AD中创建了一个应用程序,并为其提供了所有必要的权限 . 我实际上给了Microsoft Graph,app和委托的所有权限 . 他们都是 .

然后我写了我的脚本,用 https://graph.microsoft.com/v1.0/users 查询所有用户 .

我让我的租户管理员进入并接受权限,然后输出用户界面中的用户列表 . 适用于管理员

我不是管理员,但当我转到页面时,我收到以下错误:

此应用程序需要其他应用程序的应用程序权只有管理员才能同意应用程序权限 . 退出并以管理员身份登录或与您单位的管理员联系 .

我需要知道这是否适用于权限更低的用户 . 根据我的理解,API请求和应用程序在Azure中为应用程序提供的权限下运行 . 因此,即使用户为“只读”,请求也未在用户下运行,它在我设置的应用程序下运行 . 那么为什么我会收到有关权限的错误?

这是我正在使用的代码:

(function () {
  "use strict";
  // Some samples will use the tenant name here like "tenant.onmicrosoft.com"
  // I prefer to user the subscription Id
  var subscriptionId = "metenant.onmicrosoft.com";
  // Copy the client ID of your AAD app here once you have registered one, configured the required permissions, and
  // allowed implicit flow https://msdn.microsoft.com/en-us/office/office365/howto/get-started-with-office-365-unified-api
  var clientId = "cccb1f2f-xxx-x-xxxxx-x-x-x-x-x-";

  window.config = {
    // subscriptionId: subscriptionId,
    clientId: clientId,
    postLogoutRedirectUri: window.location.origin,
    endpoints: {
      graphApiUri: 'https://graph.microsoft.com'
    },
    cacheLocation: 'localStorage' // enable this for IE, as sessionStorage does not work for localhost.
  };

  var authContext = new AuthenticationContext(config);

  // Check For & Handle Redirect From AAD After Login
  var isCallback = authContext.isCallback(window.location.hash);
  authContext.handleWindowCallback();

  if (isCallback && !authContext.getLoginError()) {
    window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
  }

  // If not logged in force login
  var user = authContext.getCachedUser();
  // NOTE: you may want to render the page for anonymous users and render
  // a login button which runs the login function upon click.
  if (!user) authContext.login();

  // Acquire token for Files resource.
  authContext.acquireToken(config.endpoints.graphApiUri, function (error, token) {
    // Handle ADAL Errors.
    if (error || !token) {
      console.log('ADAL error occurred: ' + error);
      return;
    }
    // Execute GET request to Files API.
    var filesUri = config.endpoints.graphApiUri + "/v1.0/users";
    $.ajax({
      type: "GET",
      url: filesUri,
      headers: {
        'Authorization': 'Bearer ' + token,
      }
    }).done(function (response) {
      console.log('Successfully fetched from Graph.');
      console.log(response);

      var container = $(".container")

      container.empty();

      $.each(response.value, function(index, item) {
        container.append($('<li>').text(item.displayName + " " + item.mail + " " + item.mobilePhone))
      })
    }).fail(function (response) {
      var err = JSON.parse(response.responseText)
      console.log('Failed:', err.error.message);
    });
  });
})();

1 回答

  • 1

    Microsoft Graph有两种权限/范围 . 一个是需要管理员的同意 . 另一个不是必需的 .

    你为这个应用程序配置的权限是什么?要在未经管理员同意的情况下列出用户,我们可以使用范围User.ReadBasic.All如下图所示:
    enter image description here

    您可以从here获取有关权限/范围的更多详细信息 .

    Modify:

    目前,adal.js不提供管理员同意 . 如果要使用此功能,可以修改代码以添加如下所示的参数:

    AuthenticationContext.prototype.login = function (prompt) {
    // Token is not present and user needs to login
    var expectedState = this._guid();
    this.config.state = expectedState;
    this._idTokenNonce = this._guid();
    this._logstatus('Expected state: ' + expectedState + ' startPage:' + window.location);
    this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, window.location);
    this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, '');
    this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, expectedState);
    this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce);
    this._saveItem(this.CONSTANTS.STORAGE.FAILED_RENEW, '');
    this._saveItem(this.CONSTANTS.STORAGE.ERROR, '');
    this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, '');
    
    
    var urlNavigate = this._getNavigateUrl('id_token', null) + '&nonce=' + encodeURIComponent(this._idTokenNonce);
    
    if (prompt && prompt === "admin_consent") {
        urlNavigate = urlNavigate + "&prompt=admin_consent"
    }
    
    
    this.frameCallInProgress = false;
    this._loginInProgress = true;
    if (this.config.displayCall) {
        // User defined way of handling the navigation
        this.config.displayCall(urlNavigate);
    } else {
        this.promptUser(urlNavigate);
    }
    // callback from redirected page will receive fragment. It needs to call oauth2Callback
    };
    

    如果您使用的是Angular,我们还需要修改adal-angular.js:

    this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', function ($rootScope, $window, $q, $location, $timeout) {
    ... 
    return {
                    // public methods will be here that are accessible from Controller
                    config: _adal.config,
                    login: function (prompt) {
                    _adal.login(prompt);
            },
    ...
    }
    

    然后我们可以为用户登录提供两个按钮 . 一个按钮供用户自己登录 . 另一个是管理员给予组织同意 . 以下是在Angular控件中重定向到管理员同意的登录页面的代码:

    $scope.login = function () {
         adalService.login("admin_consent");
    };
    

相关问题