В чем разница между User.Read и OpenID / Profile / Email.Читать против OpenID / профиля / разрешений электронной почты в AzureAD App Регистрация приложения, которое будет входить в систему пользователей?

#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 email 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?