Я работаю с приложением ASP.NET Core 2.0, размещенным в Azure, и проверяю подлинность пользователей через Microsoft, используя MSAL. Я получаю основную информацию в процессе аутентификации, такую как имя, имя пользователя и групповые утверждения. Тем не менее, я хочу получить доступ к дополнительной информации через MS Graph, например, к фотографии профиля пользователя. Первоначальная аутентификация и получение токена проходят гладко, и отправка запроса на https://graph.microsoft.com/beta/me
возвращает 200 OK
. Однако, когда я пытаюсь позвонить https://graph.microsoft.com/beta/me/photo/$value
, я получаю 401 - Unauthorized
взамен.
Я видел несколько других постов по этой проблеме, но большинство из них приходит к выводу, что разработчик либо забыл запросить правильное согласие, либо получить токены от неправильных конечных точек, либо аналогичные проблемы. Все из которых я подтвердил, что это не так.
Я подтвердил, что в токен включены правильные области, используя https://jwt.ms/. Я также пытался запросить области большего размера, чем необходимо. В настоящее время я использую следующие области: openid profile User.ReadBasic.All User.Read.All User.ReadWrite Files.ReadWrite.All
. В соответствии с бета-ссылкой для получить пользователя наименее требуемое разрешение составляет User.Read
, а в соответствии со ссылкой для получить фотографию наименее требуемое разрешение также User.Read
. Используя Graph Explorer Я также подтвердил, что у меня должен был быть доступ к фотографии с использованием разрешений, которые я делаю, хотя я не установил никаких фотографий в своем профиле, поэтому он дает мне ответ 404
.
Я затрудняюсь понять, почему я не могу получить доступ к фотографии профиля, поэтому любые предложения очень ценятся. Если вам нужна дополнительная информация или детали, пожалуйста, дайте мне знать. Если уместно, у меня есть специальное промежуточное программное обеспечение, которое обрабатывает процесс считывания информации о пользователе после проверки подлинности, что также вызывает дополнительный вызов MS Graph для фотографии.
Edit:
Я также пытался https://graph.microsoft.com/beta/users/{my-user-id}/photo/$value
, который дал те же результаты - 404 в Graph Explorer и 401 через мой код
Редактировать 2: Код
Вот код, который я использую. Этот первый фрагмент находится в промежуточном программном обеспечении, которое помещает заявки от аутентифицированного пользователя в определенный формат. Я только что установил точку возврата для возврата и проверил объект ответа.
public async Task GetUserPhotoAsync(string userid, HttpContext context)
{
HttpClient client = new HttpClient();
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var result = await new TokenHelper(_settings).GetAuthenticationAsync(userid, context, new string[] { "User.ReadBasic.All", "User.Read.All", "User.ReadWrite", "Files.ReadWrite.All" });
var url = "https://graph.microsoft.com/beta/me/photo/$value";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
return;
}
Вот функция, которая получает токен из кэша. MSALSessionCache
- это некоторый код, который я позаимствовал у здесь с некоторыми настройками для соответствия ядру .net.
public async Task<AuthenticationResult> GetAuthenticationAsync(string signedInUserId, HttpContext context, string[] scopes)
{
TokenCache userTokenCache = new MSALSessionCache(signedInUserId, context).GetMsalCacheInstance();
ConfidentialClientApplication cca =
new ConfidentialClientApplication(_settings.ClientId, $"{_settings.Domain}/{_settings.AADInstance}/v2.0", "http://localhost:5000", new ClientCredential(_settings.ClientSecret), userTokenCache, null);
if (cca.Users.Count() > 0)
{
AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, cca.Users.First());
return result;
}
else
{
throw new Exception();
}
}
Первичное приобретение токена
options.Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = async context =>
{
string signedInUserId = context.Principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserId, context.HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca =
new ConfidentialClientApplication(aadOptions.ClientId, aadOptions.RedirectUri, new ClientCredential(aadOptions.ClientSecret), userTokenCache, null);
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(context.ProtocolMessage.Code, new string[] { "User.ReadBasic.All", "User.Read.All", "User.ReadWrite", "Files.ReadWrite.All" });
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
};
Редактировать 3: Использование конечной точки /v1.0
По запросу Марка ЛаФлёра я пробовал конечную точку v1.0 с тем же результатом. https://graph.microsoft.com/v1.0/me
дает 200 OK
код ответа, а https://graph.microsoft.com/v1.0/me/photo/$value
возвращает 401 Unauthorized