具有Web API AuthorizeAttribute角色的Azure AD OAuth客户端凭据授予流 [英] Azure AD OAuth client credentials grant flow with Web API AuthorizeAttribute Roles

查看:77
本文介绍了具有Web API AuthorizeAttribute角色的Azure AD OAuth客户端凭据授予流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

放弃

 [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客户端凭据授予流程./p>

第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 > 应用注册> [您的应用]> 端点按钮> 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 :使用 "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或类似工具进行验证,请使用 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步:保护您的秘密

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

Given

  • We have a .NET Web API service.
  • It secures access to controllers and actions using the AuthorizeAttribute with Roles. For example:

[Authorize(Roles = "Reader,Requester,Editor,Approver,Administrator")]

  • There is an App Registration within Azure Active Directory for this application.
  • It uses OAuth for user impersonation, and users are authenticating correctly. There are many tutorials available on getting to this point.

Intent

  • We wish to have an unattended scheduled process (a script) invoke REST calls on the Web API.
  • The identity of the unattended process is not available in Azure Active Directory.

    In my specific scenario, this is because we don't sync our numerous on-premises AD service accounts to AAD, and this script will be running from an on-premises service principal identity.

  • We wish to use the AuthorizeAttribute to control our script's access to controllers/actions within the Web API.

How can I make this work?

解决方案

Method

One of the constraints is that the unattended process' user identity will not exist in Azure Active Directory; so we will use OAuth 2.0 client credentials grant flow for this scenario.

Step 1: Gather Information

First, identify the following pieces of information:

  1. Client ID
  2. Tenant ID
  3. Authority Url
  4. Resource Url
  5. Client Secret

You probably already have most of these if you've got OAuth working for users and roles. If not, here is what they are and where to find them.

1a: Finding the Client ID

The client ID is a GUID, and is the application's ID in Azure Active Directory. It is not the Object ID (which is different).

Azure Portal: Azure Active Directory > App registrations > [your app] > Overview blade > Application (client) ID field.

PowerShell, from a logged-in context:

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

1b: Finding the Tenant ID

The Azure tenant ID is a GUID.

Azure Portal: Azure Active Directory > App registrations > [your app] > Overview blade > Directory (tenant) ID field.

PowerShell, from a logged-in context:

$(Get-AzContext).Tenant.Id

Azure CLI, from a logged-in context:

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

1c: Finding the Authority Url

The Authority Url is the URL of the OAuth authorization server. It looks something like this: https://login.microsoftonline.com/[your-tenant-id]/oauth2/v2.0/token

Azure Portal: Azure Active Directory > App registrations > [your app] > Endpoints button > OAuth 2.0 token endpoint (v2) field.

1d: Finding the Resource Url

The Resource Url is the URL of the Web API service. It probably looks like this: https://[yourdomain].onmicrosoft.com/[guid]

Azure Portal: Azure Active Directory > App registrations > [your app] > Expose an API blade > Application ID URI field.

It is also located in the application manifest in the identifierUris field. Azure Portal: Azure Active Directory > App registrations > [your app] > Manifest.

Manifest attribute example:

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

PowerShell, from a logged-in context:

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

Azure CLI, from a logged-in context:

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

1e: Creating the Client Secret

The client secret can be a client secret (key/password) or a certificate. Here is how to create a client secret.

Azure Portal:

  1. Go to Azure Active Directory > App registrations > [your app] > Certificates & secrets blade > Client secret section.
  2. Press the New client secret button and complete this process.
  3. Copy the key value; this is the client secret. Don't lose it.

PowerShell: use the New-AzADAppCredential cmdlet.

Step 2: Configure the Azure Active Directory Application

Since you are using AuthorizeAttribute Roles to control access, you must add the application to at least one of those roles. Roles are defined in the application manifest under the appRoles attribute.

2a: Make roles that Applications can belong to

Each role has an allowedMemberTypes attribute. If you've already configured this application for users, then you already have something like this:

"allowedMemberTypes": [
    "User"
],

To allow your application to be added to a role, modify it like this:

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

Alternately, you could have a role that allows only applications.

"allowedMemberTypes": [
    "Application"
],

2b: Add Application to its Roles

Now that there are roles that the application can belong to, you must add the application to those roles.

Azure Portal: Azure Active Directory > App registrations > [your app] > API permissions blade.

  1. Press the Add a permission button.
  2. Select the APIs my organization uses tab.
  3. Find and select your application.
  4. Press the Application permissions box.
  5. Select the permissions (roles) for this application.
  6. Finally, press the Add permissions button.

2c: Grant admin consent

If these roles require admin consent, then you will need to grant admin consent now.

Azure Portal: Azure Active Directory > App registrations > [your app] > API permissions blade > Grant consent section. Press the Grant admin consent for [your org] button, and confirm Yes.

If you don't have permissions to do this, find someone in the Application Administrator role or someone else with similar permissions to do this for you.

Step 3: Verify

At this point you should be able to use the OAuth 2.0 client credentials flow to obtain an access token, present it as a Bearer token with your request to your Web API service, and succeed.

If you want to verify using Postman or similar tool, use this guide to create the requests.

When you get your hands on a token, you can examine the contents using this tool: https://jwt.io/ Verify that there is a roles attribute in the token, and that it is populated with the roles you assigned in the previous step.

For example:

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

Here is a PowerShell script showing how to do this using the ADAL.PS module:

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

Step 4: Secure your Secret

Now you've got this secret in your unattended script or job. That's probably not a great idea, so secure that somehow. How you do it is outside the scope of this answer.

这篇关于具有Web API AuthorizeAttribute角色的Azure AD OAuth客户端凭据授予流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆