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

时间:2019-08-07 15:14:51

标签: asp.net-web-api oauth-2.0 azure-active-directory asp.net-core-webapi

放弃

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

意图

  • 我们希望有一个无人值守的计划进程(脚本)来调用Web API上的REST调用。
  • 无人参与过程的身份在Azure Active Directory中不可用。
      

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

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

我该如何进行这项工作?

1 个答案:

答案 0 :(得分:2)

方法

约束之一是无人参与进程的用户身份在Azure Active Directory中将不存在;因此在这种情况下,我们将使用OAuth 2.0 client credentials grant flow

第1步:收集信息

首先,确定以下信息:

  1. 客户ID
  2. 租户ID
  3. 权威网址
  4. 资源网址
  5. 客户秘密

如果您已经为用户和角色使用了OAuth,那么您可能已经拥有了其中的大多数功能。如果不是,这就是它们的踪影以及在哪里可以找到它们。

1a:查找客户端ID

客户端ID是GUID,并且是Azure Active Directory中应用程序的ID。 它不是对象ID(不同)。

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

PowerShell ,在登录的上下文中:

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

1b:查找租户ID

Azure租户ID是一个GUID。

Azure门户 Azure Active Directory > 应用注册> [您的应用]> 概述刀片>> em>目录(租户)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 > 应用注册> [您的应用]> 端点按钮> < em> OAuth 2.0令牌端点(v2)字段。

1d:查找资源网址

资源网址是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门户网站

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

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权限刀片。

  1. 按下添加权限按钮。
  2. 选择组织使用的 API 标签。
  3. 找到并选择您的应用程序。
  4. 应用程序权限框。
  5. 选择此应用程序的权限(角色)。
  6. 最后,按下添加权限按钮。

2c:授予管理员同意

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

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

如果您没有执行此操作的权限,请找到具有 Application Administrator 角色的人或具有类似权限的其他人为您执行此操作。

第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步:保护您的秘密

现在,您在无人看管的脚本或工作中有了这个秘密。那可能不是一个好主意,所以一定要确保它安全。您的操作方式不在此答案的范围内。