1

Я пытаюсь создать раскрывающийся список со всеми пользователями моего арендатора Office365. Я создал приложение в Azure AD и дал ему все необходимые разрешения. Я дал все разрешения для Microsoft Graph на самом деле, приложение и делегировал. Все они.Разрешения API-интерфейса Microsoft для не-админов?

Затем я написал свой сценарий, чтобы запросить всех пользователей с помощью https://graph.microsoft.com/v1.0/users.

У меня был администратор моего арендатора и принимал разрешения, а затем выводил список пользователей в пользовательском интерфейсе. Прекрасно работает для администратора

Я не админ, но когда я иду на страницу, я получаю следующее сообщение об ошибке:

This application requires application permissions to another application. Consent for application permissions can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization's administrators.

Мне нужно знать, если это будет работать для пользователей с еще более низкими разрешениями. Из того, что я понимаю, запрос 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); 
    }); 
    }); 
})(); 
+0

Похоже, что вы передаете текущий входной токен пользователя в Graph API. Вы можете дать правильное разрешение директору службы в своем арендаторе, а затем получить токен главного сервиса и использовать его для вызова Graph. – Aram

+0

Если я использую ADAL и clientID для приложения, не должен ли я передавать вход в приложение API Graph, а не текущий пользователь? Я добавил код, который я использую, чтобы сделать это – Batman

ответ

1

Есть два вида разрешений/рамки для Microsoft Graph. Один из них требует согласия администратора. Другое не требуется.

Какое разрешение вы настроили для этого приложения? Для просмотра списка пользователей без согласия администратора, мы можем использовать сферу User.ReadBasic.All как показано на рисунке ниже: enter image description here

Вы можете получить более подробную информацию о разрешении/объем от here.

Изменить:

В настоящее время adal.js не дает согласия администратора. Если вы хотите использовать эту функцию, вы можете изменить код, чтобы добавить prameter, как показано ниже:

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

Затем мы можем предоставить две кнопки для входа в систему. Одна кнопка предназначена для входа пользователей с собой. А другой - для администратора, чтобы дать согласие на организацию. Вот код, перенаправляемый на страницу входа в систему для разрешения администратора в управлении угловым:

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

Я предоставлял все разрешения, потому что у меня создалось впечатление, что запрос API будет выполняться в контексте приложения, а не в контексте пользователя. Кажется, я ошибся. Токен, отправленный через ADAL, отражает разрешения пользователей. Вот почему он терпел неудачу, потому что пользователь должен был быть администратором, так как у приложения были разрешения, требующие администратора. Когда я даю ему только разрешения, которые не являются админом, он работает нормально. – Batman

+0

Кроме того, я заметил, что каждый раз, когда пользователь входит в страницу, на которой работает ADAL, он просит их принять приложение. Но я подумал, что если администратор одобрит приложение, он не будет так себя вести. Есть идеи? – Batman

+0

Это разрешение токена зависит от того, какой поток вы его приобретете. Для учетных данных клиента маркер делегирует разрешение приложения без входа в систему. В вашем сценарии токен - это токен-делегат, который требует, чтобы у пользователей было достаточное разрешение дать согласие на приложение. Для второй проблемы, если вы хотите, чтобы администратор одобрил приложение для организации, мы должны указать его в запросе явно в первый раз. Для этого требуется добавить параметр ** prompt = admin_consent **. –