创建流分析作业时授权失败

Posted

技术标签:

【中文标题】创建流分析作业时授权失败【英文标题】:Authorization failure when creating a Stream Analytics job 【发布时间】:2015-07-17 08:51:13 【问题描述】:

我一直在尝试(但失败)以编程方式创建 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'

我做错了吗?该应用已设置委派权限。

【问题讨论】:

您是否为您的Service Principal Object 授予了适当的权限? 如果您是指第二个链接中的第 2 步,那么是的 除此之外,您还需要做一个步骤(实际上还有更多步骤,我也为此苦苦挣扎),即为订阅中为您的应用程序创建的用户分配角色Service Principal。我强烈建议您阅读这篇博文:dushyantgill.com/blog/2015/05/23/… 和此文档链接:azure.microsoft.com/en-us/documentation/articles/…。 我开始阅读那篇博文,但失去了求生的意志。我再看看,谢谢 LOL :) 几个小时后我也有同样的感觉。让我尝试提供我已采取的步骤作为答案。 【参考方案1】:

更新 - 2015 年 12 月 8 日

现在有一种简单的方法可以将角色分配给服务主体。更多详情请查看此链接: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)做其他事情。就我而言,它是一个 Web 应用程序。这是我所做的:

    我以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 用户的对象 ID。这是我在那里执行的 GET URL。对于Authorization 标头,您需要使用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 标头,您需要使用Bearer token2

    https://management.azure.com/subscriptions/subscription-id/providers/Microsoft.Authorization/roleDefinitions?api-version=2015-06-01

    接下来是将此角色分配给用户。为此,我创建了一个role assignment id 的 guid,并使用了以下 URL:

    https://management.azure.com/subscriptions/subscription-id/providers/microsoft.authorization/roleassignments/role-assignment-id?api-version=2015-06-01

这将是一个PUT 请求,请求正文将类似于:


"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

差不多了!之后您的代码应该可以正常工作:)

试一试,看看会发生什么。

【讨论】:

当我运行 Get-AzureRoleDefinition 时,我看不到任何具有与“Microsoft.StreamAnalytics/streamingjobs/write”匹配的操作的角色。还是我完全误解了这一点? 我认为这没有内置角色。请查看此链接了解所有内置角色:azure.microsoft.com/en-in/documentation/articles/…。 啊,谢谢!看起来我可以创建一个:azure.microsoft.com/en-gb/documentation/articles/… 这是将现有角色之一分配给用户(我的回答中的第 6 步)。我建议您现在尝试分配“贡献者”角色。 啊,我没看到里面的 * :) 有效,谢谢!

以上是关于创建流分析作业时授权失败的主要内容,如果未能解决你的问题,请参考以下文章

HashRouter 导致 Spotify 隐式授权流失败,因为回调 URL 无效

使用 Azure Function 作为流分析的输出:连接测试失败

Kubernetes pod 在使用未知证书授权调用谷歌云发布/订阅时失败

使用 PowerBi 的 Azure 流分析失败

OpenID Connect Core 1.0使用授权码流验证(下)

错误:流式传输作业失败:流分析作业存在验证错误:当前不支持到端点的多个输入列