asp.net-web-api - 具有Web API AuthorizeAttribute角色的Azure AD OAuth客户端凭据授予流

标签 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中的控制器/动作的访问。


我该如何工作?

最佳答案

方法

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

步骤1:收集信息

首先,确定以下信息:


客户编号
租户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:查找授权网址

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

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

1d:查找资源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”>“应用程序注册”>“ [您的应用程序]”>“证书和秘密”边栏>“客户端秘密”部分。
按“新客户端密码”按钮并完成此过程。
复制键值;这是客户的秘密。不要失去它。


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

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

关于asp.net-web-api - 具有Web API AuthorizeAttribute角色的Azure AD OAuth客户端凭据授予流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57397552/

相关文章:

azure - 将服务主体客户端 ID 和 key 传递给 ARM 模板

c# - 在 api 文件夹中使用遗留 asmx 服务的 Web Api 2 路由配置

c# - ASP.NET Web API 2 - StreamContent 非常慢

oauth-2.0 - 如何在 js webapp 中为仅承载后端客户端获取 token

azure - 将另一个 AD 中的用户添加到我的团队项目中

azure - 无法访问 onedrive

javascript - 日期、Angularjs、WebAPI

c# - WebApi 路由导致 404(未找到)响应

android - 如何在Android中用 "Login with LinkedIn"实现 "OAuth 2.0"

c# - 如何将人们的 STRAVA 个人资料与我的网站相关联?