javascript Microsoft Graph API 令牌验证失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52730511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Microsoft Graph API token validation failure
提问by infodev
I would use Microsoft Graph API in my Angular Web application.
我会在我的 Angular Web 应用程序中使用 Microsoft Graph API。
First I make connexion using msal libraryWhen I try log in with my profil I get this error
首先,我使用msal 库进行连接 当我尝试使用我的个人资料登录时,出现此错误
I have configured my app as the mentionned in the official git sample
我已将我的应用程序配置为官方git 示例中提到的
MsalModule.forRoot({
clientID: "Tenant ID",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
validateAuthority : true,
popUp: true
}),
Authetification is working and I get the token.
身份验证工作正常,我得到了令牌。
Then when I'm in home page I make a second request to Microsoft Graph API to get user information using that token.
然后,当我进入主页时,我向 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});
}
}
}
I get an 401 Unauthorized error with a response :
我收到一个 401 Unauthorized 错误的响应:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure.",
"innerError": {
"request-id": "xxxxxx",
"date": "2018-10-09T22:58:41"
}
}
}
I don't know why MG API is not accepting my token, Am I using wrong authority url ?
我不知道为什么 MG API 不接受我的令牌,我是否使用了错误的授权网址?
UPDATE: I have understood that actually I get id_token which is different from access token. How can I get Access token from MSAL library to make MS GRAPH API calls ?:
更新:我知道实际上我得到了与访问令牌不同的 id_token。如何从 MSAL 库获取访问令牌以进行 MS GRAPH API 调用?:
采纳答案by Michael Mainer
The issue is that you're using the id_token instead of the access token:
问题是您使用的是 id_token 而不是访问令牌:
let tokenid= sessionStorage.getItem('msal.idtoken');
let tokenid= sessionStorage.getItem('msal.idtoken');
becomes something like:
变成这样:
let tokenid= sessionStorage.getItem('msal.token'); // or msal.accesstoken
let tokenid= sessionStorage.getItem('msal.token'); // or msal.accesstoken
Update(per Phillipe's comment)
更新(根据菲利普的评论)
You need to select the scopes that you want to target in your application. So, it looks like you want the user profile, so you'll want to add the consentScopes property to specify which scopes your app will use:
您需要选择要在应用程序中定位的范围。因此,看起来您需要用户配置文件,因此您需要添加 permitScopes 属性来指定您的应用将使用哪些范围:
MsalModule.forRoot({
clientID: "Tenant ID",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
validateAuthority : true,
popUp: true,
consentScopes: ["user.read"]
}),
回答by Stephan
According to the same sampleyou can also attach an HttpInterceptorthat will automatically attach the access token to each (external) HTTP call.
根据同一个示例,您还可以附加一个HttpInterceptor,它会自动将访问令牌附加到每个(外部)HTTP 调用。
By reading through the documentation I found the following information.
通过阅读文档,我发现了以下信息。
consentScopes:Allows the client to express the desired scopes that should be consented. Scopes can be from multiple resources/endpoints. Passing scope here will only consent it and no access token will be acquired till the time client actually calls the API. This is optional if you are using MSAL for only login (Authentication).
同意范围:允许客户端表达应同意的所需范围。范围可以来自多个资源/端点。在这里传递范围只会同意它,并且在客户端实际调用 API 之前不会获取访问令牌。如果您仅将 MSAL 用于登录(身份验证),则这是可选的。
That suggests that using the HttpInterceptordoesn't only attach the access token, but also retrieves it. The token that you're seeing is probably just a token for your application, but isn't a valid token for the Graph API.
这表明使用HttpInterceptor不仅附加访问令牌,而且还检索它。您看到的令牌可能只是您的应用程序的令牌,但不是 Graph API 的有效令牌。
Internally it uses getCachedTokenInternal(scopes: Array<string>, user: User)to get a new access token for specific scopes code found here. I'm not sure if you can use this method as well to get a new token for that resource. I would just use the interceptor.
在内部,它用于getCachedTokenInternal(scopes: Array<string>, user: User)获取此处找到的特定范围代码的新访问令牌。我不确定您是否也可以使用此方法来获取该资源的新令牌。我只会使用拦截器。
You could try to copy the access token and see how it looks like on jwt.ms(a Microsoft provided JWT token viewer) or jwt.io.
您可以尝试复制访问令牌并查看它在jwt.ms(Microsoft 提供的 JWT 令牌查看器)或jwt.io 上的样子。
Any tokens valid for Graph should have the Audienceof https://graph.microsoft.com, so if you inspect the token (in jwt.ms) it should at least have this value.
任何标记有效的图形应该有观众的https://graph.microsoft.com,所以如果你检查令牌(在jwt.ms)至少应该有这个价值。
"aud": "https://graph.microsoft.com",
回答by Faisal Mehboob
Make sure you add your endpoint to Resource Map configuration. See this link: https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/MSALAngularDemoApp
确保将端点添加到资源映射配置中。请参阅此链接: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']] ];

