Ошибка проверки токена API Microsoft Graph
Я бы использовал Microsoft Graph API в своем угловом веб-приложении.
Сначала я подключаюсь с помощью библиотеки msal. Когда я пытаюсь войти в систему с моим профилем, я получаю эту ошибку
Я настроил свое приложение как упомянутое в официальном образце git
MsalModule.forRoot({
clientID: "Tenant ID",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
validateAuthority : true,
popUp: true
}),
Аутентификация работает, и я получаю токен.
Затем, когда я на домашней странице, я делаю второй запрос к Microsoft Graph API, чтобы получить информацию о пользователе, используя этот токен.
getProfile() {
let header= new Headers();
let tokenid= sessionStorage.getItem('msal.idtoken');
header.set('Authorization', 'Bearer ' + tokenid)
let url ="https://graph.microsoft.com/v1.0/me/"
return this.http.get(url,{headers:header});
}
}
Я получаю 401 несанкционированную ошибку с ответом:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure.",
"innerError": {
"request-id": "xxxxxx",
"date": "2018-10-09T22:58:41"
}
}
}
Я не знаю, почему MG API не принимает мой токен. Использую ли я неверный URL-адрес?
ОБНОВЛЕНИЕ: я понял, что на самом деле я получаю id_token, который отличается от токена доступа. Как получить токен доступа из библиотеки MSAL для выполнения вызовов API MS GRAPH?
2 ответа
Согласно тому же образцу вы также можете прикрепить HttpInterceptor
это автоматически прикрепит токен доступа к каждому (внешнему) HTTP-вызову.
Прочитав документацию, я нашел следующую информацию.
acceptScopes: позволяет клиентууказывать желаемые области действия, на которые следует дать согласие. Области могут быть из нескольких ресурсов / конечных точек. Передавая здесь область действия, вы только согласитесь, и токен доступа не будет получен до тех пор, пока клиент фактически не вызовет API. Это необязательно, если вы используете MSAL только для входа (Аутентификация).
Это говорит о том, что с помощью HttpInterceptor
не только прикрепляет токен доступа, но и извлекает его. Токен, который вы видите, вероятно, является просто токеном для вашего приложения, но не является допустимым токеном для Graph API.
Внутренне он используетgetCachedTokenInternal(scopes: Array<string>, user: User)
чтобы получить новый токен доступа для определенного кода области, найденного здесь. Я не уверен, что вы также можете использовать этот метод для получения нового токена для этого ресурса. Я бы просто использовал перехватчик.
Вы можете попробовать скопировать токен доступа и посмотреть, как он выглядит на jwt.ms (программа просмотра токенов JWT от Microsoft) или jwt.io.
Любые токены, действительные для Graph, должны иметь аудиторию https://graph.microsoft.com
, так что если вы проверяете токен (в jwt.ms), он должен как минимум иметь это значение.
"aud": "https://graph.microsoft.com",
Проблема в том, что вы используете id_token вместо токена доступа:
let tokenid= sessionStorage.getItem('msal.idtoken');
становится что-то вроде:
let tokenid= sessionStorage.getItem('msal.token'); // or msal.accesstoken
Обновление(согласно комментарию Филиппа)
Вам нужно выбрать области, на которые вы хотите ориентироваться в вашем приложении. Итак, похоже, что вам нужен профиль пользователя, поэтому вы захотите добавить свойство grantScopes, чтобы указать, какие области будет использовать ваше приложение:
MsalModule.forRoot({
clientID: "Tenant ID",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
validateAuthority : true,
popUp: true,
consentScopes: ["user.read"]
}),
Убедитесь, что вы добавили свою конечную точку в конфигурацию карты ресурсов. См. Эту ссылку: https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/MSALAngularDemoApp
export const protectedResourceMap:[string, string[]][]=[ ['https://graph.microsoft.com/v1.0/me', ['user.read']] ];