2017-01-11 7 views
2

У нас есть зарегистрированное веб-приложение в Azure AD, для которого требуется действительный токен OAuth. Обычно поток аутентификации поступает из пользовательского интерфейса Javascript, токен OAuth передается из промежуточного программного обеспечения в целевое приложение REST целевого веб-API, он проверяет токен на ValidAudiences, и все отлично работает.Azure AD: AcquireTokenAsync для собственного приложения терпит неудачу, когда appRoleAssignmentRequired = true

Теперь у нас есть пользователь, не являющийся пользователем: еще одна служба, которая нуждается в доступе к этому приложению. Для этого в Azure AD было создано новое «родное» приложение с ключом (секретным) для аутентификации. Приложение имеет три разрешения API: Azure Active Directory, Windows Azure Service Management API и приложение для доступа.

Чтобы получить маркер аутентификации нового приложения, мы используем следующий код:

private static async Task<string> Authenticate(
    string tenant, string clientId, 
    string appKey, string resource) 

{ 
    var authority = $"https://login.windows.net/{tenant}/oauth2/token"; 
    var credential = new ClientCredential(clientId, appKey); 
    var authContext = new AuthenticationContext(authority); 
    var result = await authContext.AcquireTokenAsync(resource, credential); 
    return result.AccessToken; 
} 

, где tenant является ID нашей организации («XXXX.onmicrosoft.com»), clientId является идентификатор приложения из новый сервис (потребитель), appKey является сгенерированным ключом, а resource - это идентификатор приложения целевого веб-приложения, к которому нам нужен доступ.

Это работало до тех пор, пока мы не столкнулись с ситуацией, когда доступ к целевому приложению был ограничен, разрешив «Требуемое назначение пользователя»? переключаться и перечислять разрешенных пользователей явно в настройках приложения. После этого этот код начал неудачу со следующим сообщением:

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS50105: Application «{наш идентификатор клиента}» не назначается роли для приложения «{ целевое веб-приложение}.

Оказывается, этот параметр задает appRoleAssignmentRequired свойства в ServicePrincipal целевого приложения к true. Googling подтвердил, что Azure AD хранит список разрешенных участников в объектах AppRoleAssignment для Принципа Сервиса приложения и не выдает токены клиентам, не входящим в этот список.

В этом списке нет пользовательского интерфейса, чтобы добавлять приложения (а не пользователей). Теперь API Azure AD Graph появляется. Мы были в состоянии проверить список назначенных пользователей, используя следующий запрос:

https://graph.windows.net/{tenant}/servicePrincipals/{id}/appRoleAssignedTo 

(id является услуга принципа целевого приложения, плюс запрос должен иметь действительный маркер однонаправленного).

К сожалению, мы не смогли определить способ добавления нашего приложения (принципала обслуживания) в этот список.

Мы попробовали как Azure AD Graph (graph.windows.net), так и API графиков Microsoft (graph.microsoft.com). Первый метод упоминается в this post, вместе с запиской она сломана:

ПРИМЕЧАНИЕ: В настоящее время уступка обслуживания долга к ресурсу сломано, и мы будем работать, чтобы решить эту проблему, и обновлять этот пост, когда это фиксированная.

Второй метод документируется here и сослались in this Stack Overflow post, опять-таки с упоминанием, что есть ошибка.

Я пропустил что-то действительно простое здесь? Поддерживает ли AppRoleAssignment добавление приложений вообще? Решает ли наша проблема ограниченного доступа?

Спасибо, Виталий

ответ

0

Вместо использования appRoleAssignedTo, мы можем использовать appRoleAssignments назначить основную службу в другую.

Вот образец для справки:

POST: https://graph.windows.net/{tenantId}/servicePrincipals/{naiveServicePrincipalId}/appRoleAssignments?api-version=1.6 
content-type: application/json 
{ 
    "id":"00000000-0000-0000-0000-000000000000", 
    "principalId":"{naiveServicePrincipalId}", 
    "principalType":"ServicePrincipa", 
    "resourceId":"{webAPIServicePrincipalId}" 
}