使用 Microsoft Graph SDK for Powershell 将角色分配给应用服务主体?
Using Microsoft Graph SDK for Powershell to Assign Role to App Service Principal?
我正在使用 https://github.com/microsoftgraph/msgraph-sdk-powershell,因为我的脚本需要 Powershell 7 支持,AzureAD 模块在我发现的 Windows 上除了 Powershell 5 之外还有很多问题。基本上,我正在尝试在 B2C 租户中创建应用程序注册。我遇到的问题是我的脚本看起来不错,但我无法授予任何管理员对定义的任何范围的同意。然后我注意到了这个问题 - 当您在门户中创建应用程序注册时,它会自动获取服务主体,New-MgApplication
不会。
我有以下有效的脚本,直到我尝试使用 New-MgServicePrincipalAppRoleAssignment
将服务主体分配给我的应用程序,它因错误而崩溃:New-MgServicePrincipalAppRoleAssignment_CreateExpanded: Not a valid reference update.
我不确定这个功能是否适合我的需要,或者 New-MgRoleManagementDirectoryRoleAssignment
是否是正确的功能。
function Upsert-AppRegistration {
Param(
[string] $TemplateParametersFile,
[string] $ResourceGroupName
)
$templateParameters = Get-Content $TemplateParametersFile | ConvertFrom-Json
$customerName = $templateParameters.parameters.customerName.value
$deploymentIdentifier = $templateParameters.parameters.deploymentIdentifier.value
$b2cTenantId = $templateParameters.parameters.b2cTenantId.value
$b2cTenantName = $templateParameters.parameters.b2cTenantName.value
$GraphConnection = Connect-Graph -TenantId $b2cTenantId -Scopes "User.Read","User.ReadWrite.All","Mail.ReadWrite",`
"Directory.ReadWrite.All","Chat.ReadWrite", "People.Read", `
"Group.Read.All", "Directory.AccessAsUser.All", "Tasks.ReadWrite", `
"Sites.Manage.All"
[string[]]$webRedirectUris =
"https://localhost:5050/LoginView",
"https://localhost:5050/DashboardView",
"https://localhost:5050/UsersView",
"https://localhost:5050/OrdersView"
# Our custom app.login scope for delegated permissions from front-end login
$oauth2PermissionScopes = @{
"Id" = [guid]::NewGuid().guid
"Value" = "app.login"
"AdminConsentDescription" = "This will provide the application access to login"
"AdminConsentDisplayName" = "Admin delegated login"
"IsEnabled" = $true
"Type" = "Admin"
}
[object[]]$appLoginScope = @{
"Id" = $oauth2PermissionScopes.Id
"Type" = "Scope"
}
# Microsoft.Graph ResourceAccess scopes and roles
$mgOfflineAccessScope = @{
"Id" = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"
"Type" = "Scope"
}
$mgOpenidScope = @{
"Id" = "37f7f235-527c-4136-accd-4a02d197296e"
"Type" = "Scope"
}
$mgDirectoryReadWriteAllRole = @{
"Id" = "19dbc75e-c2e2-444c-a770-ec69d8559fc7"
"Type" = "Role"
}
$mgResourceAccess = $mgOfflineAccessScope, $mgOpenidScope, $mgDirectoryReadWriteAllRole
[object[]]$requiredResourceAccess = @{
"ResourceAppId" = "00000003-0000-0000-c000-000000000000"
"ResourceAccess" = $mgResourceAccess
}
$mgApplicationParams = @{
"DisplayName" = "${customerName}-${deploymentIdentifier}"
"ApiOauth2PermissionScopes" = $oauth2PermissionScopes
"ApiRequestedAccessTokenVersion" = 2
"ImplicitGrantSettingEnableAccessTokenIssuance" = $true
"ImplicitGrantSettingEnableIdTokenIssuance" = $true
"RequiredResourceAccess" = $requiredResourceAccess
"WebLogoutUrl" = "https://localhost:5050/LogoutView"
"WebRedirectUris" = $webRedirectUris
"IdentifierUris" = "https://$b2cTenantName.onmicrosoft.com/app"
}
# We need to create our application before we can add permissions to our custom scope
$mgApplication = New-MgApplication @mgApplicationParams
# Now our application has an Id so we can finish setting up the RequiredResourceAccess
$newRequiredResourceAccess = $requiredResourceAccess + @{
"ResourceAppId" = $mgApplication.AppId
"ResourceAccess" = $appLoginScope
}
# Azure doesn't always update immediately, make sure app exists before we try to update its config
$appExists = $false
while (!$appExists) {
Start-Sleep -Seconds 2
$appExists = Get-MgApplication -ApplicationId $mgApplication.Id
}
$mgApplicationParams.Add("ApplicationId", $mgApplication.Id)
$mgApplicationParams.RequiredResourceAccess = $newRequiredResourceAccess
Update-MgApplication @mgApplicationParams
$appServicePrincipal = New-MgServicePrincipal -AppId $mgApplication.AppId -Tags @("WindowsAzureActiveDirectoryIntegratedApp")
$result = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id `
-AppRoleId 19dbc75e-c2e2-444c-a770-ec69d8559fc7 `
-ResourceId 429a2356-9cdc-475e-8caf-cfe8b7c77db8 `
-PrincipalType "ServicePrincipal"
# @TODO Generate app client secret
$appClientSecret = "--SECRET--"
Write-Host "Created the app registration ${customerName}-${deploymentIdentifier} with client Id:",
$mgApplication.AppId -ForegroundColor Yellow
@{
"appClientId" = $mgApplication.AppId
"appClientSecret" = $appClientSecret
}
}
事实证明,我不需要为我的服务主体分配角色,因为它可以正常工作并且所有内容都可以正确显示。这是 Azure UI 滞后和关键是在服务主体中添加标签的组合,当我发布这个时我还没有测试过。
我正在使用 https://github.com/microsoftgraph/msgraph-sdk-powershell,因为我的脚本需要 Powershell 7 支持,AzureAD 模块在我发现的 Windows 上除了 Powershell 5 之外还有很多问题。基本上,我正在尝试在 B2C 租户中创建应用程序注册。我遇到的问题是我的脚本看起来不错,但我无法授予任何管理员对定义的任何范围的同意。然后我注意到了这个问题 - 当您在门户中创建应用程序注册时,它会自动获取服务主体,New-MgApplication
不会。
我有以下有效的脚本,直到我尝试使用 New-MgServicePrincipalAppRoleAssignment
将服务主体分配给我的应用程序,它因错误而崩溃:New-MgServicePrincipalAppRoleAssignment_CreateExpanded: Not a valid reference update.
我不确定这个功能是否适合我的需要,或者 New-MgRoleManagementDirectoryRoleAssignment
是否是正确的功能。
function Upsert-AppRegistration {
Param(
[string] $TemplateParametersFile,
[string] $ResourceGroupName
)
$templateParameters = Get-Content $TemplateParametersFile | ConvertFrom-Json
$customerName = $templateParameters.parameters.customerName.value
$deploymentIdentifier = $templateParameters.parameters.deploymentIdentifier.value
$b2cTenantId = $templateParameters.parameters.b2cTenantId.value
$b2cTenantName = $templateParameters.parameters.b2cTenantName.value
$GraphConnection = Connect-Graph -TenantId $b2cTenantId -Scopes "User.Read","User.ReadWrite.All","Mail.ReadWrite",`
"Directory.ReadWrite.All","Chat.ReadWrite", "People.Read", `
"Group.Read.All", "Directory.AccessAsUser.All", "Tasks.ReadWrite", `
"Sites.Manage.All"
[string[]]$webRedirectUris =
"https://localhost:5050/LoginView",
"https://localhost:5050/DashboardView",
"https://localhost:5050/UsersView",
"https://localhost:5050/OrdersView"
# Our custom app.login scope for delegated permissions from front-end login
$oauth2PermissionScopes = @{
"Id" = [guid]::NewGuid().guid
"Value" = "app.login"
"AdminConsentDescription" = "This will provide the application access to login"
"AdminConsentDisplayName" = "Admin delegated login"
"IsEnabled" = $true
"Type" = "Admin"
}
[object[]]$appLoginScope = @{
"Id" = $oauth2PermissionScopes.Id
"Type" = "Scope"
}
# Microsoft.Graph ResourceAccess scopes and roles
$mgOfflineAccessScope = @{
"Id" = "7427e0e9-2fba-42fe-b0c0-848c9e6a8182"
"Type" = "Scope"
}
$mgOpenidScope = @{
"Id" = "37f7f235-527c-4136-accd-4a02d197296e"
"Type" = "Scope"
}
$mgDirectoryReadWriteAllRole = @{
"Id" = "19dbc75e-c2e2-444c-a770-ec69d8559fc7"
"Type" = "Role"
}
$mgResourceAccess = $mgOfflineAccessScope, $mgOpenidScope, $mgDirectoryReadWriteAllRole
[object[]]$requiredResourceAccess = @{
"ResourceAppId" = "00000003-0000-0000-c000-000000000000"
"ResourceAccess" = $mgResourceAccess
}
$mgApplicationParams = @{
"DisplayName" = "${customerName}-${deploymentIdentifier}"
"ApiOauth2PermissionScopes" = $oauth2PermissionScopes
"ApiRequestedAccessTokenVersion" = 2
"ImplicitGrantSettingEnableAccessTokenIssuance" = $true
"ImplicitGrantSettingEnableIdTokenIssuance" = $true
"RequiredResourceAccess" = $requiredResourceAccess
"WebLogoutUrl" = "https://localhost:5050/LogoutView"
"WebRedirectUris" = $webRedirectUris
"IdentifierUris" = "https://$b2cTenantName.onmicrosoft.com/app"
}
# We need to create our application before we can add permissions to our custom scope
$mgApplication = New-MgApplication @mgApplicationParams
# Now our application has an Id so we can finish setting up the RequiredResourceAccess
$newRequiredResourceAccess = $requiredResourceAccess + @{
"ResourceAppId" = $mgApplication.AppId
"ResourceAccess" = $appLoginScope
}
# Azure doesn't always update immediately, make sure app exists before we try to update its config
$appExists = $false
while (!$appExists) {
Start-Sleep -Seconds 2
$appExists = Get-MgApplication -ApplicationId $mgApplication.Id
}
$mgApplicationParams.Add("ApplicationId", $mgApplication.Id)
$mgApplicationParams.RequiredResourceAccess = $newRequiredResourceAccess
Update-MgApplication @mgApplicationParams
$appServicePrincipal = New-MgServicePrincipal -AppId $mgApplication.AppId -Tags @("WindowsAzureActiveDirectoryIntegratedApp")
$result = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appServicePrincipal.Id `
-AppRoleId 19dbc75e-c2e2-444c-a770-ec69d8559fc7 `
-ResourceId 429a2356-9cdc-475e-8caf-cfe8b7c77db8 `
-PrincipalType "ServicePrincipal"
# @TODO Generate app client secret
$appClientSecret = "--SECRET--"
Write-Host "Created the app registration ${customerName}-${deploymentIdentifier} with client Id:",
$mgApplication.AppId -ForegroundColor Yellow
@{
"appClientId" = $mgApplication.AppId
"appClientSecret" = $appClientSecret
}
}
事实证明,我不需要为我的服务主体分配角色,因为它可以正常工作并且所有内容都可以正确显示。这是 Azure UI 滞后和关键是在服务主体中添加标签的组合,当我发布这个时我还没有测试过。