#azure-active-directory #microsoft-graph-api #microsoft-graph-teams
#azure-active-directory #microsoft-graph-api #microsoft-graph-teams
Вопрос:
При создании многопользовательских приложений, которые будут использовать проверку подлинности Azure AD для входа пользователей, различные примеры на GitHub, похоже, предполагают, что регистрация приложения должна включать следующие разрешения, включенные в OpenID.
email View users' email address
offline_access Maintain access to data you have given it access to
openid Sign users in
profile View users' basic profile
(См., Например: https://github.com/OfficeDev/microsoft-teams-sample-auth-node Раздел 12)
Следуя примерам на самом портале Azure, quickstarts создает регистрацию приложения только с этим одним разрешением
Пользователь.Прочитайте «Войдите в систему» и прочитайте «Профиль пользователя»
Является пользователем Azure AD от Microsoft.Разрешение на чтение — это надмножество общих разрешений openid на электронную почту, openid и профиль?
При создании URL-адреса согласия в https://login.microsoftonline.com/common/adminconsent?client_id ={client-id} форма, только Пользователь.Кажется, появляется Read.
Какой рекомендуемый набор разрешений рекомендуется для базового приложения, в котором требуется вход пользователей?
Ответ №1:
Я просто потратил довольно много времени на тестирование этого в рамках моего собственного обучения сегодня, и вот что я обнаружил.
tl; dr
Область openid
действия даст вам an id_token
, и an access_token
, который позволяет вам вызывать конечную точку userInfo (https://graph.microsoft.com/oidc/userinfo ). Если вы хотите вызвать любой из API-интерфейсов Graph (кроме userInfo), то вам понадобится (по крайней мере) область User.Read
видимости.
Подробности
У меня есть тестовый клиент AzureAD, в котором я создал совершенно новую регистрацию клиентского приложения (с конечной точкой SPA) и совершенно нового пользователя, таким образом гарантируя, что нигде не было остаточного «согласия».
Затем я использовал браузер для входа в систему с помощью созданного вручную URL-адреса, чтобы запросить только openid
область действия. С добавлением разрывов строк и некоторыми отредактированными символами это было:
https://login.microsoftonline.com/a8257b21-...6263/oauth2/v2.0/authorize?
client_id=b3f87624-...e5bamp;
response_type=codeamp;
redirect_uri=https://localhostamp;
response_mode=queryamp;
scope=openidamp;
state=12345amp;
code_challenge=LrTIpxRwK...
code_challenge_method=S256amp;
prompt=login
Для этого я получил приведенное ниже приглашение на согласие:
Интересно отметить, что в нем было предложено «Просмотреть ваш базовый профиль» и «Поддерживать доступ к данным …«, когда я не запрашивал области profile
или offline_access
.
Я извлек код авторизации из ответа и отправил его на https://login.microsoftonline.com/{{tenant_id}}/oauth2/v2.0/token
конечную точку с необходимыми полями.
В id_token
ответном сообщении не содержалось утверждений profile
, которые подразумевала бы область, показаны только следующие
{
"aud": "b3f87624-...2fb5367e5b",
"iss": "https://login.microsoftonline.com/a8257b21...263/v2.0",
"iat": 1642367777,
"nbf": 1642367777,
"exp": 1642371677,
"rh": "0.AUYAIXs...L7U2fluAAB0.",
"sub": "tcK...WXUvzWqAc",
"tid": "a82...6263",
"uti": "SjLRuw...jlhAA",
"ver": "2.0"
}
Однако, что интересно access_token
, возвращенное для Graph
аудитории ( 00000003-0000-0000-c000-000000000000
) перечисляло области как включающие profile
и email
, и включало утверждения, связанные с ними, например (с некоторыми опущенными для ясности)
{
"aud": "00000003-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/a82...6263/",
"app_displayname": "TestApp",
"appid": "b3f87...67e5b",
"family_name": "Bull",
"given_name": "Pit",
"idtyp": "user",
"ipaddr": "67.183.2.129",
"name": "Pit Bull",
"oid": "08a5...673de",
"scp": "openid profile email",
"sub": "6JrD7...phCH7Y",
"tid": "a825...36263",
"unique_name": "pit@example.dev",
"upn": "pit@example.dev",
"ver": "1.0"
}
(Примечание: очевидно, что вы не должны искать токены, которые не предназначены для вашей аудитории, но все это есть в открытом виде, так?)
Я также вернул токен обновления, который я сохранил на потом.
С помощью этого токена доступа я мог бы вызвать конечную точку userInfo, а также просмотреть *name
утверждения, которые будут указывать profile
область действия (я забыл установить email
для своего тестового пользователя, иначе, я предполагаю, это тоже было бы показано).
Из https://graph.microsoft.com/oidc/userinfo
{
"sub": "tcK6D...UvzWqAc",
"name": "Pit Bull",
"family_name": "Bull",
"given_name": "Pit",
"picture": "https://graph.microsoft.com/v1.0/me/photo/$value"
}
Однако с тем же токеном доступа, если я попытаюсь вызвать какие-либо API Graph, такие как https://graph.microsoft.com/v1.0/me или https://graph.microsoft.com/v1.0/organization Я был встречен следующим ответом.
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"date": "2022-01-16T21:52:18",
"request-id": "e4f58...1611",
"client-request-id": "e4f5...a1611"
}
}
}
Снова выполнив тот же поток, но на этот раз с областями openid profile email
, единственное отличие, которое я смог установить, заключалось в том, что id_token
теперь в него включены приведенные ниже утверждения (и, опять же, вероятно, был бы указан адрес электронной почты, если бы я настроил его в учетной записи)
"name": "Pit Bull",
"oid": "08a5...73de",
"preferred_username": "pit@example.dev",
Маркер доступа выглядел так же, и результат userInfo был таким же (что имеет смысл, если access_token для авторизации к нему выглядел так же). Я также хотел бы отметить, что мне не было предложено получить какое-либо дополнительное согласие, которое подразумевало profile
бы и email
было неявно добавлено к моему первоначальному openid
запросу только для области действия.
На этом этапе я сделал перерыв, чтобы покормить детей, и когда я вернулся через пару часов, решил попробовать полученный токен обновления (без запроса offline_access
области действия). Это сработало нормально, и я получил обновленные токены, так что, похоже, это неявно добавляется и при простом запросе openid
.
Для моего следующего теста я отправил тот же созданный вручную запрос на аутентификацию, но включил User.Read
область действия. Как и ожидалось, мне было предложено получить дополнительное согласие:
Интересно отметить, как в нем упоминается «.. и прочитайте основную информацию о компании«. Это согласуется с документами по адресу https://docs.microsoft.com/en-us/graph/permissions-reference какое состояние User.Read
: «С пользователем.Разрешение на чтение приложение также может считывать основную информацию о компании пользователя, вошедшего в систему для рабочей или школьной учетной записи, через ресурс организации.«.
Все токены, которые я получил от этого, выглядели так же, как и раньше, но, очевидно, с добавлением User.Read
scp в токен доступа. Теперь выполнение запросов к определенным графическим API-интерфейсам увенчалось успехом. Например:
https://graph.microsoft.com/v1.0/me или https://graph.microsoft.com/v1.0/users/pit@example.dev
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
"businessPhones": [],
"displayName": "Pit Bull",
"givenName": "Pit",
"jobTitle": null,
"mail": null,
"mobilePhone": null,
"officeLocation": null,
"preferredLanguage": null,
"surname": "Bull",
"userPrincipalName": "pit@example.dev",
"id": "08a53...b673de"
}
https://graph.microsoft.com/v1.0/me/directReports (У меня не было настроено никаких прямых отчетов, но это был успешный запрос, а не отказ в доступе)
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#directoryObjects",
"value": []
}
И https://graph.microsoft.com/v1.0/organization (обрезано для удобства чтения — и опять же, я бы не стал настраивать данные организации для этой учетной записи, отсюда null
и s)
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#organization",
"value": [
{
"id": "a8257...736263",
"businessPhones": [],
"city": null,
"country": null,
"postalCode": null,
"preferredLanguage": null,
"state": null,
"tenantType": "AAD",
"directorySizeQuota": {
"used": 39,
"total": 300000
},
"verifiedDomains": [
{
"capabilities": "Email, OfficeCommunicationsOnline",
"isDefault": false,
"isInitial": true,
"name": "example.onmicrosoft.com",
"type": "Managed"
},
{
"capabilities": "None",
"isDefault": true,
"isInitial": false,
"name": "example.dev",
"type": "Managed"
}
]
}
]
}
Итак, у вас это есть. Добавьте User.Read
, если вы хотите запросить что-либо из Graph API, в противном случае просто используйте openid
(и необязательно profile email
), если вы довольны, просто регистрируя пользователей и используя id_token
для своих нужд.
В качестве сноски к этому я бы также рекомендовал прочитать пару абзацев по адресу https://docs.microsoft.com/en-us/graph/permissions-reference#remarks-15 . Я тестировал только с конечной точкой v2, но, похоже User.Read
, раньше это требовалось только для входа в систему с конечной точкой v1, поэтому включение по умолчанию может быть остаточным эффектом этого. Как говорится о конечной точке V1: «Чтобы успешно вернуть токен ID, вы также должны убедиться, что пользователь.Разрешение на чтение настраивается при регистрации приложения. »
Комментарии:
1. Большое спасибо за тщательное тестирование и за документирование этого.
2. То, что я извлекаю из этого,
User.Read
в основном эквивалентноopenid
profile
дает вам доступ к Graph API. А также,offline_access
на самом деле ничего не делает, потомуrefresh_token
что будет включено либоopenid
илиUser.Read
Ответ №2:
Отсюда вопрос, включает ли user.read в open_id, email и profile perms?
Нет, user.read
не содержит их, они являются независимыми разрешениями.
Я установил эти необходимые разрешения, но во всплывающем окне согласия, показанном администратору Azure AD, разрешения электронной почты, профиля и OpenID не отображаются; отображаются только offlne_access и user.read.
email
offline_access
openid
profile
обычно это разрешения протокола OIDC. Существуют некоторые различия между oauth2.0 и openid connect. Если вам нужно только войти в систему как пользователь, вам нужно только использовать openid connect, и он вернет вам только идентификационный токен вошедшего в систему пользователя. Что касается того, почему профиль openid электронной почты не отображается на странице согласия администратора, я думаю, что это проблема, которая все еще решается, но я не думаю, что вам нужно беспокоиться об этом, потому что сами эти разрешения являются разрешениями, которые не требуют согласия администратора. Когда вы добавляете их в разрешения API, вы можете использовать их напрямую.
Комментарии:
1. Если мой ответ полезен для вас, вы можете принять его как ответ (нажмите на галочку рядом с ответом, чтобы переключить его с выделенного серым цветом на заполненный). Спасибо!
Ответ №3:
В это время разрешения offline_access («Поддерживать доступ к данным, к которым вы предоставили ему доступ») и user.read («Войдите в систему и прочитайте свой профиль») автоматически включаются в первоначальное согласие на приложение. Эти разрешения обычно требуются для правильной работы приложения — offline_access предоставляет приложению доступ к токенам обновления, критически важным для собственных и веб-приложений, в то время как user.read предоставляет доступ к дополнительному утверждению, позволяя клиенту или приложению корректно идентифицировать пользователя с течением времени и получать доступ к элементарной информации о пользователе. пожалуйста, ознакомьтесь с этим документом
Комментарии:
1. Спасибо. Я предполагаю, что вопрос заключается в том, когда мы просим согласия администратора иностранного арендатора, нужно ли нам специально запрашивать openid, адрес электронной почты, профиль или user.read предоставляет ту же информацию. В моем многопользовательском приложении я установил эти необходимые разрешения, но во всплывающем окне согласия, показанном администратору Azure AD, разрешения электронной почты, профиля и openid не отображаются; отображаются только offlne_access и user.read. Отсюда вопрос, включает ли user.read в open_id, email и profile perms?