创建流分析作业时授权失败
Authorization failure when creating a Stream Analytics job
我一直在尝试(但失败了)以编程方式创建 Azure 流分析作业。我最初是在关注这个例子:
https://azure.microsoft.com/en-gb/documentation/articles/stream-analytics-dotnet-management-sdk/
但它会弹出一个对话框供您登录。我希望能够在服务器端执行此操作。看来我需要使用 Azure AD 才能使用资源管理器 API。我一直在努力解决这个问题:
https://msdn.microsoft.com/en-us/library/azure/dn790557.aspx#bk_portal
代码如下所示:
var authContext = new AuthenticationContext("https://login.microsoftonline.com/{tenant id}/oauth2/token");
var clientId = "{app client id}";
var appKey = "{app key}";
var subscriptionId = "{subscription id}";
var clientCredential = new ClientCredential(clientId, appKey);
var result = authContext.AcquireToken("https://management.core.windows.net/", clientCredential);
var creds = new TokenCloudCredentials(subscriptionId, result.AccessToken);
var client = new StreamAnalyticsManagementClient(creds);
var jobCreateParameters = new JobCreateOrUpdateParameters
{
Job = new Job
{
Name = streamAnalyticsJobName,
Location = "North Europe",
Properties = new JobProperties
{
EventsOutOfOrderPolicy = EventsOutOfOrderPolicy.Adjust,
Sku = new Sku
{
Name = "Standard"
}
}
}
};
var jobCreateResponse = client.StreamingJobs.CreateOrUpdate(resourceGroupName, jobCreateParameters);
我可以成功获取令牌,但创建作业失败:
AuthorizationFailed: The client 'REDACTED' with object id 'REDACTED' does not have authorization to perform action 'Microsoft.StreamAnalytics/streamingjobs/write' over scope '/subscriptions/REDACTED/resourcegroups/REDACTED/providers/Microsoft.StreamAnalytics/streamingjobs/REDACTED'
我做错了什么吗?该应用已设置委派权限。
更新 - 2015 年 12 月 8 日
现在有一种简单的方法可以将角色分配给服务主体。请参阅此 link 了解更多详情:https://azure.microsoft.com/en-in/documentation/articles/resource-group-create-service-principal-portal/.
原始回复
当您向 Azure 订阅授予对应用程序的访问权限时,会在后台使用您的 Azure AD 中的 Service Principal
用户类型创建一个用户。您在下面使用的代码假定您在获取访问令牌时使用此 Service Principal
用户。
var clientCredential = new ClientCredential(clientId, appKey);
var result = authContext.AcquireToken("https://management.core.windows.net/", clientCredential);
var creds = new TokenCloudCredentials(subscriptionId, result.AccessToken);
但是默认情况下,此用户未被授予对您的订阅的任何权限 (RBAC),这就是您收到授权错误的原因。
要解决此问题,您需要在您的订阅中为该用户授予适当的角色。现在您可以使用 PowerShell
来执行此操作,或者您可以使用 ADAL 库通过代码 + 发出一些 Web 请求来执行此操作。
我所做的是使用 ADAL 库获取访问令牌,然后使用 Google Postman
(或 Fiddler
)做其他事情。就我而言,它是一个网络应用程序。这是我所做的:
我以 Global Administrator
(订阅所有者)身份登录到应用程序并获得 code
。使用 code
和 ADAL 库,我获得了访问令牌(我们称之为 token1
)。
var authContext = new AuthenticationContext(string.Format("{0}/common", signinEndpoint));//signinEndpoint = https://login.windows.net
var result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, redirectUri, credential);
我复制了上面result
中返回给我的租户ID和访问令牌。
接下来我做的是使用 POSTMAN 找到 Service Principal
用户的 object id。这是我在那里执行的 GET URL。对于 Authorization
header,您需要使用 Bearer {token1}
.
https://graph.windows.net/{subscription-id}/servicePrincipals?api-version=1.5&$filter=appId eq '{app-client-id}'
之后,我使用以下代码为服务管理 API 操作获取了另一个访问令牌(我们称之为 token2
):
authContext = new AuthenticationContext(string.Format("{0}/{1}", signinEndpoint, result.TenantId));
result = await authContext.AcquireTokenSilentAsync(serviceManagementApiEndpoint, credential, new UserIdentifier(request.UserInfo.UniqueId, UserIdentifierType.UniqueId));//serviceManagementApiEndpoint = https://management.core.windows.net/
之后,我在我的订阅中列出了角色,并选择了我想分配给我的 Service Principal
用户的角色。在我的例子中,我想分配一个 Reader
角色,所以我记下了角色的 ID。对于 Authorization
header,您需要使用 Bearer {token2}
.
https://management.azure.com/subscriptions/{subscription-id}/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-06-01
接下来是将此角色分配给用户。为此,我创建了一个 guid 作为 role assignment id
并使用了以下 URL:
https://management.azure.com/subscriptions/{subscription-id}/providers/microsoft.authorization/roleassignments/{role-assignment-id}?api-version=2015-06-01
这将是一个 PUT
请求,这是请求 body 将类似于:
{
"properties":
{
"roleDefinitionId": "{role id of the selected role from step 5}",
"principalId": "{id of the service principal from step 3"
}
}
请确保请求的 content-type
设置为 application/json;odata=verbose
而不是 application/json
.
差不多就这些了!之后你的代码应该可以正常工作了:)
试一试,看看会发生什么。
我一直在尝试(但失败了)以编程方式创建 Azure 流分析作业。我最初是在关注这个例子:
https://azure.microsoft.com/en-gb/documentation/articles/stream-analytics-dotnet-management-sdk/
但它会弹出一个对话框供您登录。我希望能够在服务器端执行此操作。看来我需要使用 Azure AD 才能使用资源管理器 API。我一直在努力解决这个问题:
https://msdn.microsoft.com/en-us/library/azure/dn790557.aspx#bk_portal
代码如下所示:
var authContext = new AuthenticationContext("https://login.microsoftonline.com/{tenant id}/oauth2/token");
var clientId = "{app client id}";
var appKey = "{app key}";
var subscriptionId = "{subscription id}";
var clientCredential = new ClientCredential(clientId, appKey);
var result = authContext.AcquireToken("https://management.core.windows.net/", clientCredential);
var creds = new TokenCloudCredentials(subscriptionId, result.AccessToken);
var client = new StreamAnalyticsManagementClient(creds);
var jobCreateParameters = new JobCreateOrUpdateParameters
{
Job = new Job
{
Name = streamAnalyticsJobName,
Location = "North Europe",
Properties = new JobProperties
{
EventsOutOfOrderPolicy = EventsOutOfOrderPolicy.Adjust,
Sku = new Sku
{
Name = "Standard"
}
}
}
};
var jobCreateResponse = client.StreamingJobs.CreateOrUpdate(resourceGroupName, jobCreateParameters);
我可以成功获取令牌,但创建作业失败:
AuthorizationFailed: The client 'REDACTED' with object id 'REDACTED' does not have authorization to perform action 'Microsoft.StreamAnalytics/streamingjobs/write' over scope '/subscriptions/REDACTED/resourcegroups/REDACTED/providers/Microsoft.StreamAnalytics/streamingjobs/REDACTED'
我做错了什么吗?该应用已设置委派权限。
更新 - 2015 年 12 月 8 日
现在有一种简单的方法可以将角色分配给服务主体。请参阅此 link 了解更多详情:https://azure.microsoft.com/en-in/documentation/articles/resource-group-create-service-principal-portal/.
原始回复
当您向 Azure 订阅授予对应用程序的访问权限时,会在后台使用您的 Azure AD 中的 Service Principal
用户类型创建一个用户。您在下面使用的代码假定您在获取访问令牌时使用此 Service Principal
用户。
var clientCredential = new ClientCredential(clientId, appKey);
var result = authContext.AcquireToken("https://management.core.windows.net/", clientCredential);
var creds = new TokenCloudCredentials(subscriptionId, result.AccessToken);
但是默认情况下,此用户未被授予对您的订阅的任何权限 (RBAC),这就是您收到授权错误的原因。
要解决此问题,您需要在您的订阅中为该用户授予适当的角色。现在您可以使用 PowerShell
来执行此操作,或者您可以使用 ADAL 库通过代码 + 发出一些 Web 请求来执行此操作。
我所做的是使用 ADAL 库获取访问令牌,然后使用 Google Postman
(或 Fiddler
)做其他事情。就我而言,它是一个网络应用程序。这是我所做的:
我以
Global Administrator
(订阅所有者)身份登录到应用程序并获得code
。使用code
和 ADAL 库,我获得了访问令牌(我们称之为token1
)。var authContext = new AuthenticationContext(string.Format("{0}/common", signinEndpoint));//signinEndpoint = https://login.windows.net var result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, redirectUri, credential);
我复制了上面
result
中返回给我的租户ID和访问令牌。接下来我做的是使用 POSTMAN 找到
Service Principal
用户的 object id。这是我在那里执行的 GET URL。对于Authorization
header,您需要使用Bearer {token1}
.https://graph.windows.net/{subscription-id}/servicePrincipals?api-version=1.5&$filter=appId eq '{app-client-id}'
之后,我使用以下代码为服务管理 API 操作获取了另一个访问令牌(我们称之为
token2
):authContext = new AuthenticationContext(string.Format("{0}/{1}", signinEndpoint, result.TenantId)); result = await authContext.AcquireTokenSilentAsync(serviceManagementApiEndpoint, credential, new UserIdentifier(request.UserInfo.UniqueId, UserIdentifierType.UniqueId));//serviceManagementApiEndpoint = https://management.core.windows.net/
之后,我在我的订阅中列出了角色,并选择了我想分配给我的
Service Principal
用户的角色。在我的例子中,我想分配一个Reader
角色,所以我记下了角色的 ID。对于Authorization
header,您需要使用Bearer {token2}
.https://management.azure.com/subscriptions/{subscription-id}/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-06-01
接下来是将此角色分配给用户。为此,我创建了一个 guid 作为
role assignment id
并使用了以下 URL:https://management.azure.com/subscriptions/{subscription-id}/providers/microsoft.authorization/roleassignments/{role-assignment-id}?api-version=2015-06-01
这将是一个 PUT
请求,这是请求 body 将类似于:
{
"properties":
{
"roleDefinitionId": "{role id of the selected role from step 5}",
"principalId": "{id of the service principal from step 3"
}
}
请确保请求的 content-type
设置为 application/json;odata=verbose
而不是 application/json
.
差不多就这些了!之后你的代码应该可以正常工作了:)
试一试,看看会发生什么。