Azure AD OAuth 客户端凭据授予流与 Web API AuthorizeAttribute 角色

Posted

技术标签:

【中文标题】Azure AD OAuth 客户端凭据授予流与 Web API AuthorizeAttribute 角色【英文标题】:Azure AD OAuth client credentials grant flow with Web API AuthorizeAttribute Roles 【发布时间】:2019-12-15 06:38:43 【问题描述】:

给定

我们有一个 .NET Web API 服务。 它使用AuthorizeAttribute 和Roles 保护对控制器和操作的访问。例如:
[Authorize(Roles = "Reader,Requester,Editor,Approver,Administrator")]
此应用程序在 Azure Active Directory 中有一个应用程序注册。 它使用 OAuth 进行用户模拟,并且用户正在正确进行身份验证。有很多教程可以帮助您了解这一点。

意图

我们希望有一个无人参与的计划进程(脚本)在 Web API 上调用 REST 调用。 无人参与进程的标识在 Azure Active Directory 中不可用。

在我的特定场景中,这是因为我们没有将大量本地 AD 服务帐户同步到 AAD,并且此脚本将从本地服务主体身份运行。

我们希望使用AuthorizeAttribute 来控制我们的脚本对 Web API 中的控制器/操作的访问。

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

方法

其中一个限制是无人参与进程的用户身份将不存在于 Azure Active Directory 中;所以我们将在这个场景中使用OAuth 2.0 client credentials grant flow。

第 1 步:收集信息

首先,确定以下信息:

    客户 ID 租户 ID 授权网址 资源网址 客户端密码

如果您已经让 OAuth 为用户和角色工作,那么您可能已经拥有其中的大部分。如果没有,这里是它们的位置以及在哪里可以找到它们。

1a:查找客户端 ID

客户端 ID 是一个 GUID,是应用程序在 Azure Active Directory 中的 ID。 不是对象 ID(不同)。

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > 概述刀片 > 应用程序(客户端)ID 字段。

PowerShell,来自登录的上下文:

$(Get-AzADApplication -DisplayName "[your app name]").ApplicationId.Guid

1b:查找租户 ID

Azure 租户 ID 是一个 GUID。

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > 概述刀片 > 目录(租户)ID 字段。

PowerShell,来自登录的上下文:

$(Get-AzContext).Tenant.Id

Azure CLI,来自登录的上下文:

az account show --query 'tenantId' -o tsv

1c:查找权威网址

Authority Url 是 OAuth 授权服务器的 URL。它看起来像这样:https://login.microsoftonline.com/[your-tenant-id]/oauth2/v2.0/token

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > 端点 按钮 > OAuth 2.0 令牌端点 (v2) 字段。

1d:查找资源 URL

Resource Url 是 Web API 服务的 URL。大概是这样的:https://[yourdomain].onmicrosoft.com/[guid]

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > 公开 API 刀片> 应用程序 ID URI 字段。

它也位于identifierUris 字段的应用程序清单中。 Azure 门户Azure Active Directory > 应用注册 > [您的应用] > 清单

清单属性示例:

"identifierUris": [
    "https://[yourdomain].onmicrosoft.com/[guid]"
]

PowerShell,来自登录的上下文:

$(Get-AzADApplication -ApplicationId [ClientId]).IdentifierUris

Azure CLI,来自登录的上下文:

az ad app show --id [ClientId] --query 'identifierUris' -o tsv

1e:创建客户端密码

客户端密码可以是客户端密码(密钥/密码)或证书。以下是创建客户端密码的方法。

Azure 门户

    转到 Azure Active Directory > 应用注册 > [您的应用] > 证书和机密 刀片 > 客户端机密 em> 部分。新建客户端密码按钮并完成此过程。 复制键值;这是客户的秘密。不要丢失它。

PowerShell:使用New-AzADAppCredential cmdlet。

步骤 2:配置 Azure Active Directory 应用程序

由于您使用AuthorizeAttribute 角色来控制访问,因此您必须将应用程序添加到这些角色中的至少一个。角色在 应用程序清单 中的 appRoles 属性下定义。

2a:创​​建应用程序可以属于的角色

每个角色都有一个allowedMemberTypes 属性。如果您已经为用户配置了这个应用程序,那么您已经有了这样的东西:

"allowedMemberTypes": [
    "User"
],

要允许将您的应用程序添加到角色,请像这样修改它:

"allowedMemberTypes": [
    "User",
    "Application"
],

或者,您可以拥有一个只允许应用程序的角色。

"allowedMemberTypes": [
    "Application"
],

2b:将应用程序添加到其角色

既然有应用程序可以属于的角色,您必须将应用程序添加到这些角色中。

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > API 权限 刀片。

    添加权限按钮。 选择我的组织使用的API选项卡。 查找并选择您的应用程序。 按应用程序权限框。 为此应用程序选择权限(角色)。 最后,按下添加权限按钮。

2c:授予管理员同意

如果这些角色需要管理员同意,那么您现在需要授予管理员同意。

Azure 门户Azure Active Directory > 应用注册 > [您的应用] > API 权限 刀片 > 同意部分。按为 [您的组织] 授予管理员同意 按钮,然后确认

如果您没有执行此操作的权限,请寻找具有 应用程序管理员 角色的人员或具有类似权限的其他人员为您执行此操作。

第 3 步:验证

此时,您应该能够使用 OAuth 2.0 客户端凭据流来获取访问令牌,将其作为不记名令牌与您对 Web API 服务的请求一起呈现,然后成功。

如果您想使用 Postman 或类似工具进行验证,请使用 this guide 创建请求。

当您拿到一个令牌时,您可以使用此工具检查其内容:https://jwt.io/ 验证令牌中是否有 roles 属性,并且它是否填充了您在之前分配的角色一步。

例如:


    …
  "azpacr": "1",
  "roles": [
    "Approver",
    "Reader"
  ],
  "ver": "2.0"
    …

这里是一个 PowerShell 脚本,展示了如何使用 ADAL.PS 模块执行此操作:

Import-Module ADAL.PS
$tenantId = "[tenant id]"
$authority = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/authorize"
$resourceUrl = "[resource url]"
$clientId = "[client id]"
$secret = ConvertTo-SecureString -String [client secret] -AsPlainText -Force
$response = Get-ADALToken -Authority $authority -Resource $resourceUrl -ClientId $clientId -ClientSecret $secret
$token = $response.AccessToken
$response
$restResponse = Invoke-RestMethod -Method Get -Uri "[your web api uri]" -ContentType "application/json; charset=utf-8" -Headers @ Authorization = "Bearer $token"  -Verbose -Debug
$restResponse

第 4 步:保护您的秘密

现在,您在无人看管的脚本或工作中掌握了这个秘密。这可能不是一个好主意,所以以某种方式确保安全。你如何做到这一点超出了这个答案的范围。

【讨论】:

以上是关于Azure AD OAuth 客户端凭据授予流与 Web API AuthorizeAttribute 角色的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 5 客户端凭据授予与 azure 广告

AAD B2C 中具有客户端凭据授予流的 Azure 应用服务轻松身份验证

Office 365 客户端凭据中的错误回调授予 OAuth2 流

如何在使用 OAuth2 的资源所有者密码凭据授予类型时对客户端凭据保密

Azure AD 应用程序注册中的 Client Secret 最长到期时间修改为 2 年

Spring OAuth2 - 客户端凭据授予类型中的用户信息