oauth-2.0 - 无法从 SPA 前端 Web 应用程序的图形 api 获取照片
问题描述
我正在使用 ADAL js 对用户进行身份验证,并且我能够成功地对用户进行身份验证。我能够获取图形 api 的令牌并使用以下 url 读取用户配置文件。
GET
https://graph.microsoft.com/v1.0/me
但我无法阅读用户个人资料图片:
https://graph.microsoft.com/v1.0/me/photo/$value
我收到以下错误
Object { code: "NoPermissionsInAccessToken", message: "The token contains no permissions, or permissions can not be understood.", innerError: {…} }
我已经设置了所需的权限:
在收到 401 错误之前在标头中发送的 JWT 的内容:
{
"typ": "JWT",
"nonce": "IenxIPCU1ue14Z9bIIxEidRBBCTnL52w4Q",
"alg": "RS256",
"x5t": "huN95IvPf34GzBDZ1GXGirnM",
"kid": "huN95hq34GzBGXGirnM"
}
JWT 令牌的正文:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/6f1dc6d4-8e90-4593/",
"iat": 1596560469,
"nbf": 1596560469,
"exp": 1596564369,
"acct": 1,
"acr": "1",
"aio": "ATQAy/8QAAAAf64iQ9pAkP+bk/JnXpSNXFPVFqvW/urra8A2QueWm2xaJZM+",
"altsecid": "5::100320A47F8DD5",
"amr": [
"wia"
],
"app_displayname": "graphdemo-dev",
"appid": "dsfkj32-4350-44a4-dd33-f45b7172b0cd",
"appidacr": "0",
"email": "email@domain.com",
"family_name": "faily",
"given_name": "given",
"idp": "https://sts.windows.net/deff24bb-2089-4400378b2/",
"in_corp": "true",
"ipaddr": "70.50.13.18",
"oid": "dskfs77s-5bc6-4fbe-b59a-11fbc2",
"platf": "3",
"puid": "A9BDE43D",
"scp": "profile User.Read User.Read.All User.ReadBasic.All User.ReadWrite User.ReadWrite.All",
"sub": "r4-9Ra9nHTjU-g1PvuXwh18",
"tenant_region_scope": "NA",
"tid": "d4-8e90-4599-af70-13a4289b3",
"unique_name": "email@domain.com",
"uti": "MDGPXbP3lUJMyAA",
"ver": "1.0",
"xms_tcdt": 8700342
}
注意:我使用随机字符删除和更新了机密数据。
当我尝试使用 Graph Explorer 时:
Need admin approval
Graph explorer (official site)
microsoft.com
Graph explorer (official site) needs permission to access resources in your organization that only an admin can grant. Please ask an admin to grant permission to this app before you can use it.
import AuthenticationContext from 'adal-angular/lib/adal.js';
// KPMG
const config = {
tenant: process.env.VUE_APP_AZUREAD_TENANTID,
clientId: process.env.VUE_APP_AZUREAD_CLIENTID,
cacheLocation: process.env.VUE_APP_CACHE_LOCATION,
redirectUri: process.env.VUE_APP_REDIRECT_URI
};
export default {
authenticationContext: null,
/**
* @return {Promise}
*/
initialize() {
this.authenticationContext = new AuthenticationContext(config);
return new Promise((resolve, reject) => {
if (this.authenticationContext.isCallback(window.location.hash) || window.self !== window.top) {
// redirect to the location specified in the url params.
this.authenticationContext.handleWindowCallback();
}
else {
// try pull the user out of local storage
const user = this.authenticationContext.getCachedUser();
if (user) {
this.authenticationContext.config.extraQueryParameter = 'login_hint=' + user.userName;
resolve();
}
else {
// no user at all - go sign in..
this.signIn();
}
}
});
},
我使用下面的代码来获取图形 api 令牌
acquireGraphApiToken() {
return new Promise((resolve, reject) => {
this.authenticationContext.acquireToken('https://graph.microsoft.com', (error, graphApiToken) => {
if (error || !graphApiToken) {
this.signOut();
return reject(error);
} else {
return resolve(graphApiToken);
}
});
});
},
解决方案
For Microsoft Graph explorer, you need to sign in with an admin account and do the admin consent like this:
Do the admin consent:
And from the screenshot above, you can see the access token. After you finish the admin consent, you can decode the access token to see if it includes the required permissions.
For you own Azure AD application, I see that you have done the admin consent based on your screenshot. It's hard to say where the problem is. So my suggestion is to try the admin consent endpoint:
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/v2.0/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
&scope=
https://graph.microsoft.com/calendars.read
https://graph.microsoft.com/mail.send
Access this url in a browser using an admin account and finish the consent. If the issue still exists, you can create a new Azure AD application and only add the required permission User.Read
(Don't add other permissions).
推荐阅读
- laravel - 使用laravel和inertiaJs上传文件更新数据时加载响应数据失败
- docker - 执行 docker run 后容器启动时运行 .sh 脚本
- javascript - 将 TypeScript 类型打印到控制台/文件中
- php - Laravel:文件中为 foreach() 提供的参数无效
- django - FastAPI 生态系统是否具有类似于 Django 存储的功能?
- javascript - 如何遍历json对象数据并将字符串拆分为变量
- ruby-on-rails - 如何将我的 SQLite3 查询转换为 postgreSQL?
- c# - discord js如何检查消息是否有用户ID示例:.ban [userid]
- python - 尝试使用 coremltools 4.1 将模型转换为 coreml 不工作
- .net - 使用 Nant 问题在 Windows 10 上为 dotnet 2 dll 创建开发环境