无法通过 Azure Powershell 在新应用程序注册模块中设置 "preAuthorizedApplications" 对象

Cannot set "preAuthorizedApplications" object in new App registrations module through Azure Powershell

短场景:多租户前端javascript (React.JS) Web 应用程序调用多租户ASP.NET Core 2.2 WebAPI 来自浏览器。

身份验证:

  1. ADAL.js 在前端应用程序中负责从 AzureAD1 或 AzureAD2 或 AzureAD3 获取令牌...当用户登录时(基于用户的原始 Azure Active目录)。

  2. 用户同意委托给 Web 的前端 Web 应用程序(范围:登录并读取用户配置文件)API 也。 (表示用户也不需要同意网络API

  3. 前端Web App使用bearer token调用WebAPI获取资源

问题:我必须自动部署新环境。并相应地设置清单文件(这是一个 SaaS 解决方案)

  1. 在清单文件中,我需要为客户端应用程序公开 WebAPI (https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis#expose-a-new-scope-through-the-ui)
  2. 设置 "knownClientApplications" 是不够的(由于前面描述的委派
  3. 新的 v2 端点 (https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-overview) 具有新的应用程序注册功能。旧版本现在称为 "Legacy",将从 2019 年 5 月开始弃用。
  4. 在 Azure 门户中需要公开 API 并将前端 WebApp 添加为 "Authorized cient applications"。

此步骤将在清单文件中添加一个新对象:

"preAuthorizedApplications": [
        {
            "appId": "guid",
            "permissionIds": [
                "guid"
            ]
        }
    ],
  1. 但它仍然无法通过 PowerShell 使用! (https://docs.microsoft.com/en-us/powershell/module/azuread/set-azureadapplication?view=azureadps-2.0)

如何使用 Azure PowerShell 将此 "preAuthorizedApplications" 部分添加到清单文件中?为什么它在门户中可用,但在 PS 中不可用?通常是相反的...

08-05-2019 根据回答更新:

我正在通过服务主体获取访问令牌:

$adTokenUrl = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$resource = "https://graph.windows.net/"

$body = @{
    grant_type    = "client_credentials"
    client_id     = "$ServicePrincipalId"
    client_secret = "$ServicePrincipalKey"
    resource      = "$resource"
}

$response = Invoke-RestMethod -Method 'Post' -Uri $adTokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token

根据文档:https://docs.microsoft.com/en-us/graph/api/application-update?view=graph-rest-beta&tabs=cs

服务主体应至少具有 Application.ReadWrite.OwnedBy 和大多数 Application.ReadWrite.All 权限。

我是否应该要求我们的 AAD 管理员将以下权限授予服务主体?



08-05-2019 更新 2:服务委托人已被授予上述所有突出显示的权利。

尝试 1:

第 1 步:通过服务主体获取 access_token(Api 应用程序的所有者将被更新)

$adTokenUrl = "https://login.microsoftonline.com/$(TenantId)/oauth2/token"
$resource = "https://graph.microsoft.com/"

$body = @{
    grant_type    = "client_credentials"
    client_id     = "$(ServicePrincipalId)"
    client_secret = "$(ServicePrincipalKey)"
    resource      = "$resource"
}

$response = Invoke-RestMethod -Method 'Post' -Uri $adTokenUrl -ContentType "application/x-www-form-urlencoded" -Body $body
$token = $response.access_token

第 2 步:使用此 access_token,根据 Md Farid Uddin Kiron 的建议构建我的 PATCH 请求,并且

Result: The remote server returned an error: (403) Forbidden.

09-05-2019 更新 3: 经过一些友好和详细的解释和指导后,我让它工作并为我的 Postman 请求获取 HTTP 204。唯一剩下的就是将这些步骤集成到我的管道中。

See accepted answer. It works. If someone has the same issue, please read the other answer from Md Farid Uddin Kiron.

你说得对,AzureAD powershell 模块似乎有问题。那对我也不起作用。

如果您想使用 powershell 修改您的 app manifest 以添加 "preAuthorizedApplications" 部分,您可以尝试下面的 powershell 脚本。

我已经在我这边测试过了,它对我有用。

理论上,我调用了Microsoft Graph API来修改app manifest。如果您有任何进一步的疑虑,请随时告诉我。

$AdAdminUserName = "<-your Azure ad admin username ->"

$AdAdminPass="<-your Azure ad admin password ->"

$AdAppObjId = "<-your app obj id->"

$AdPreAuthAppId = "<-the app that need to be pre authed ->"

$AdAppScopeId = "<-your app scope id->"

$tenantName = "<-your tenant name->"


$body=@{
    "grant_type"="password";
    "resource"="https://graph.microsoft.com/";
    "client_id"="1950a258-227b-4e31-a9cf-717495945fc2";
    "username"=$AdAdminUserName;
    "password" = $AdAdminPass
}

$requrl = "https://login.microsoftonline.com/"+$tenantName+"/oauth2/token" 

$result=Invoke-RestMethod -Uri $requrl -Method POST -Body $body 

$headers = New-Object 'System.Collections.Generic.Dictionary[String,String]'
$headers.Add("Content-Type","application/json")
$headers.Add("Authorization","Bearer " + $result.access_token)


$preAuthBody = "{`"api`": {`"preAuthorizedApplications`": [{`"appId`": `"" + $AdPreAuthAppId + "`",`"permissionIds`": [`"" + $AdAppScopeId + "`"]}]}}"

$requrl= "https://graph.microsoft.com/beta/applications/"+$AdAppObjId

Invoke-RestMethod -Uri $requrl -Method PATCH -Body  $preAuthBody  -Headers $headers

Note: ROPC is not safe as Microsoft does not recommend to use that. It also does not allow to use MFA that is why it is little dangerous.

对另一个回复的一些补充。

实际上,在 AzureADPreview powershell module, there is a parameter -PreAuthorizedApplications for Set-AzureADApplication. But neither the cmdlet help nor the documentation page has been updated to detail all these, it was also mentioned here

我不确定参数是否有效,根据我的测试,我总是收到错误的请求错误。即使我调用 Azure AD Graph API,我也会收到同样的错误。命令 Set-AzureADApplication 本质上调用 Azure AD Graph API,因此如果参数有效,它也适用于 API。此外,在 AAD Graph 文档中,没有这样的 属性。根据测试结果,该参数目前似乎不起作用。 (不清楚,如有不妥,请指正)

即使我授予所有 Microsoft Graph API 和 AAD API 应用程序相关权限。这真的很奇怪。 但是,使用密码流获取 Azure AD 管理员帐户下的访问令牌将能够成功调用此 API:

更新

您可以通过以下步骤获得您的 client idclient secret

  1. 转到 azure active directory 菜单上的 azure portal 查看屏幕 下方热门:

  1. 一旦你 select azure active directory 你会看到 App registrations 单击它。然后 select 你的申请。见下图

  1. 在您的申请中,您会看到 client idtenant idclient secret 标记在下面的屏幕截图中:

如果您还有任何疑虑,请随时分享。谢谢,编码愉快!

解决令牌问题我这样做了(如果您有 az 订阅所有者,在这种情况下,您可以获得令牌,它允许更新 aad 拥有的应用程序属性,而无需 aad 管理员登录名和密码)。订阅所有者 az 登录后:

$msGraphAccess = az account get-access-token --resource "https://graph.microsoft.com | 
ConvertFrom-Json
$accessToken = $msGraphAccess.accessToken

$headers = New-Object 'System.Collections.Generic.Dictionary[String,String]'
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", "Bearer " + $accessToken)

如果您想避免直接调用图形 API(也许您在使用服务连接的 Azure 管道中并且无权访问凭据),您可以这样做:

$AppName = << WebApp >>
$preAuthorizedApplicationsAppId = <<GUID>>

# Get the application and delegated permission to pre-authorize
$appRegistration = Get-AzureADMSApplication -Filter "displayName eq '$AppName'"
$oauth2Permission = $appRegistration.Api.OAuth2PermissionScopes | Where-Object {$_.Value -eq $AppName -and $_.Type -eq 'Admin'}

# Build a PreAuthorizedApplication object
$preAuthorizedApplication = New-Object 'Microsoft.Open.MSGraph.Model.PreAuthorizedApplication'
$preAuthorizedApplication.AppId = $preAuthorizedApplicationsAppId
$preAuthorizedApplication.DelegatedPermissionIds = @($oauth2Permission.Id)

$appRegistration.Api.PreAuthorizedApplications = New-Object 'System.Collections.Generic.List[Microsoft.Open.MSGraph.Model.PreAuthorizedApplication]'
$appRegistration.Api.PreAuthorizedApplications.Add($preAuthorizedApplication)

# Update the Application object
Set-AzureADMSApplication -ObjectId $appRegistration.Id -Api $appRegistration.Api

此答案来自此GitHub issue