使用 /token 端点获取授权访问令牌
Obtain authorization access token using /token endpoint
我正在创建一个 python 应用程序,它将使用 Microsoft Security Graph API。我已经关注 the sample provided here 没有任何问题。我现在希望能够创建一个 python 应用程序,它可以在不使用网络浏览器的情况下获取访问令牌(并在需要时刷新它)。
到目前为止,我已经在 Delegated Permissions
和 Application Permissions
下创建了一个具有 SecurityEvent.Read.All
和 SecurityEvent.ReadWrite.All
权限的新应用程序。然后,我在 Web 浏览器中转到以下 url 以授予我的应用程序同意并使用我的租户管理员登录:
https://login.microsoftonline.com/common/adminconsent?
client_id=APPLICATION_ID
&state=12345
&redirect_uri=REDIRECT_URL
接下来,我假设我想跟随the steps here 进行POST 调用以获取令牌。下面是我如何做的一个例子。
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=d)
以下是我收到的回复
{
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 0,
"access_token": "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFDNXVuYTBFVUZnVElGOEVsYXh0V2pUR2cxQV9PR0FJWmx3T1V0b2hMNHdWN2hURHVoQTJSTzIyQnY0cGljcGJ2UmkwdEdpcmY0Q2cxaDhRZF9RamUzX2l0LUhfT1VhTnJRaDFxYXpINWtIRENBQSIsImFsZyI6IlJTMjU2IiwieDV0IjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIiwia2lkIjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIn0.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNTQwNDE3MjI0LCJuYmYiOjE1NDA0MTcyMjQsImV4cCI6MTU0MDQyMTEyNCwiYWlvIjoiNDJSZ1lMRDUvK2RINkplbC9EK1RHRmZlaVNqMUJnQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJTZWN1cml0eSBHcmFwaCBQT0MiLCJhcHBpZCI6IjMxMjA0MGRmLWIyZmUtNDI1Ni04ZWZkLTk1NDYyOTVjNWZhNyIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0Ny8iLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJnLUtlY1dkZXcwQzV2cjBoLUhGZ0FBIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjEyODkyNDE1NDd9.JGu6fjJk_vVvG_4NYRBfZto6nW9YRWh43JzhrlcFqFYAnJSJvWDlHbzka_H3gUKkZernQanzjI6AumER9mOtapmj1qhu_58pCuL2lTl2ubj1MTBTYOpUX3hlKgN16AeyvjO1x95LKDO9xAcIYLXEmwbkNw87x7YxZ1lKBA59c1BCCILmqMf86E7CDExf7EPqbqAPdCI6FPkStx5CJ0YnvAN2Uk5EHloTL3BTXMqMmT05h7OAvZRogkIk4aeGof1OXKcqXw7dJbzYg8XiEeXdAYhA1ld6VEwiVBMSpqf4w476Ksvr8JUbg-xhAmGoU8CrXBB4em5Gv2ko89-qP49nUA"
}
使用现在获得的访问令牌,我正在尝试调用 /alerts
端点。下面是如何完成的。
headers = {
"Content-type": "application/json",
"Authorization": "Bearer " + <access_token>,
}
alerts = requests.get("https://graph.microsoft.com/v1.0/security/alerts", headers=headers)
我没有得到返回的警报,而是响应:
{
"error": {
"code": "UnknownError",
"message": "Auth token does not contain valid permissions or user does not have valid roles. Please see document at https://techcommunity.microsoft.com/t5/Using-Microsoft-Graph-Security/Authorization-and-Microsoft-Graph-Security-API/m-p/184376",
"innerError": {
"request-id": "1319d099-7b14-4eb0-9834-4614d5231085",
"date": "2018-10-24T21:23:16"
}
}
}
我的权限有问题吗?
Why is this getting returned for me? Am I missing a step?
您混淆了图形 API 和 AAD 图形 API。您应该遵循以下 docs 来实施客户端凭据流程:
Register your app.
Configure permissions for Microsoft Graph on your app.
Get administrator consent.
Get an access token.
Use the access token to call Microsoft Graph.
以及有关如何使用的更多信息 Graph Security API。
你非常接近。这里的问题是 scope
值 https://graph.microsoft.com/v1.0/security/alerts/.default
不正确。
如果您希望使用安全 API,则需要在您的应用程序注册中包含 SecurityEvents.Read.All
或 SecurityEvents.ReadWrite.All
(通过 https://apps.dev.microsoft.com)。
Important: Whenever you change the scopes for your application, you must repeat the Admin Consent process. Admin Consent only applies to the scopes you had configured at the time Consent was granted.
完成后,您需要告诉 /token
端点使用预先注册的范围。这是通过将 scope
属性 设置为 https://graph.microsoft.com/.default
来完成的。你在这里做的是告诉它你想使用 Microsoft Graph (https://graph.microsoft.com/
) 的预注册 (.default
) 范围:
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token", data=d)
更新
您使用的 /token
端点还有一个问题。使用 client_credentials
时,您 不能 使用 /common
租户。由于没有用户进行身份验证,因此 AAD 无法发现它应该针对哪个租户进行身份验证。在不知道哪个租户的情况下,它无法确定应该应用哪些范围,这反过来会导致没有任何范围的令牌。
您需要明确提供要为其获取令牌的租户 ID。您可以使用租户的 ID(GUID)或域:
https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token
https://login.microsoftonline.com/tenantdomain.onmicrosoft.com/oauth2/v2.0/token
我正在创建一个 python 应用程序,它将使用 Microsoft Security Graph API。我已经关注 the sample provided here 没有任何问题。我现在希望能够创建一个 python 应用程序,它可以在不使用网络浏览器的情况下获取访问令牌(并在需要时刷新它)。
到目前为止,我已经在 Delegated Permissions
和 Application Permissions
下创建了一个具有 SecurityEvent.Read.All
和 SecurityEvent.ReadWrite.All
权限的新应用程序。然后,我在 Web 浏览器中转到以下 url 以授予我的应用程序同意并使用我的租户管理员登录:
https://login.microsoftonline.com/common/adminconsent?
client_id=APPLICATION_ID
&state=12345
&redirect_uri=REDIRECT_URL
接下来,我假设我想跟随the steps here 进行POST 调用以获取令牌。下面是我如何做的一个例子。
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=d)
以下是我收到的回复
{
"token_type": "Bearer",
"expires_in": 3600,
"ext_expires_in": 0,
"access_token": "eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFDNXVuYTBFVUZnVElGOEVsYXh0V2pUR2cxQV9PR0FJWmx3T1V0b2hMNHdWN2hURHVoQTJSTzIyQnY0cGljcGJ2UmkwdEdpcmY0Q2cxaDhRZF9RamUzX2l0LUhfT1VhTnJRaDFxYXpINWtIRENBQSIsImFsZyI6IlJTMjU2IiwieDV0IjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIiwia2lkIjoiaTZsR2szRlp6eFJjVWIyQzNuRVE3c3lISmxZIn0.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNTQwNDE3MjI0LCJuYmYiOjE1NDA0MTcyMjQsImV4cCI6MTU0MDQyMTEyNCwiYWlvIjoiNDJSZ1lMRDUvK2RINkplbC9EK1RHRmZlaVNqMUJnQT0iLCJhcHBfZGlzcGxheW5hbWUiOiJTZWN1cml0eSBHcmFwaCBQT0MiLCJhcHBpZCI6IjMxMjA0MGRmLWIyZmUtNDI1Ni04ZWZkLTk1NDYyOTVjNWZhNyIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0Ny8iLCJ0aWQiOiI3MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDciLCJ1dGkiOiJnLUtlY1dkZXcwQzV2cjBoLUhGZ0FBIiwidmVyIjoiMS4wIiwieG1zX3RjZHQiOjEyODkyNDE1NDd9.JGu6fjJk_vVvG_4NYRBfZto6nW9YRWh43JzhrlcFqFYAnJSJvWDlHbzka_H3gUKkZernQanzjI6AumER9mOtapmj1qhu_58pCuL2lTl2ubj1MTBTYOpUX3hlKgN16AeyvjO1x95LKDO9xAcIYLXEmwbkNw87x7YxZ1lKBA59c1BCCILmqMf86E7CDExf7EPqbqAPdCI6FPkStx5CJ0YnvAN2Uk5EHloTL3BTXMqMmT05h7OAvZRogkIk4aeGof1OXKcqXw7dJbzYg8XiEeXdAYhA1ld6VEwiVBMSpqf4w476Ksvr8JUbg-xhAmGoU8CrXBB4em5Gv2ko89-qP49nUA"
}
使用现在获得的访问令牌,我正在尝试调用 /alerts
端点。下面是如何完成的。
headers = {
"Content-type": "application/json",
"Authorization": "Bearer " + <access_token>,
}
alerts = requests.get("https://graph.microsoft.com/v1.0/security/alerts", headers=headers)
我没有得到返回的警报,而是响应:
{
"error": {
"code": "UnknownError",
"message": "Auth token does not contain valid permissions or user does not have valid roles. Please see document at https://techcommunity.microsoft.com/t5/Using-Microsoft-Graph-Security/Authorization-and-Microsoft-Graph-Security-API/m-p/184376",
"innerError": {
"request-id": "1319d099-7b14-4eb0-9834-4614d5231085",
"date": "2018-10-24T21:23:16"
}
}
}
我的权限有问题吗?
Why is this getting returned for me? Am I missing a step?
您混淆了图形 API 和 AAD 图形 API。您应该遵循以下 docs 来实施客户端凭据流程:
Register your app. Configure permissions for Microsoft Graph on your app. Get administrator consent. Get an access token. Use the access token to call Microsoft Graph.
以及有关如何使用的更多信息 Graph Security API。
你非常接近。这里的问题是 scope
值 https://graph.microsoft.com/v1.0/security/alerts/.default
不正确。
如果您希望使用安全 API,则需要在您的应用程序注册中包含 SecurityEvents.Read.All
或 SecurityEvents.ReadWrite.All
(通过 https://apps.dev.microsoft.com)。
Important: Whenever you change the scopes for your application, you must repeat the Admin Consent process. Admin Consent only applies to the scopes you had configured at the time Consent was granted.
完成后,您需要告诉 /token
端点使用预先注册的范围。这是通过将 scope
属性 设置为 https://graph.microsoft.com/.default
来完成的。你在这里做的是告诉它你想使用 Microsoft Graph (https://graph.microsoft.com/
) 的预注册 (.default
) 范围:
d = {
"client_id": <client_id>,
"scope": ["https://graph.microsoft.com/.default"],
"client_secret": <client_secret>,
"grant_type": "client_credentials"
}
r = requests.post("https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token", data=d)
更新
您使用的 /token
端点还有一个问题。使用 client_credentials
时,您 不能 使用 /common
租户。由于没有用户进行身份验证,因此 AAD 无法发现它应该针对哪个租户进行身份验证。在不知道哪个租户的情况下,它无法确定应该应用哪些范围,这反过来会导致没有任何范围的令牌。
您需要明确提供要为其获取令牌的租户 ID。您可以使用租户的 ID(GUID)或域:
https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0/token
https://login.microsoftonline.com/tenantdomain.onmicrosoft.com/oauth2/v2.0/token