如何无需全局管理员角色部署azuread_claims_mapping_policy?
我尝试通过Terraform部署azuread_claims_mapping_policy,但因权限不足失败,错误信息如下:
│ Error: retrieving Claims Mapping Policy with object ID: "<GUID HERE>" │ │ with azuread_claims_mapping_policy.integration_claims_mapping[0], │ on active_directory.tf line 54, in resource "azuread_claims_mapping_policy" "integration_claims_mapping": │ 54: resource "azuread_claims_mapping_policy" "integration_claims_mapping" { │ │ ClaimsMappingPolicyClient.BaseClient.Get(): unexpected status 403 with │ OData error: Authorization_RequestDenied: Insufficient privileges to │ complete the operation.
代码通过托管标识执行。根据Terraform AzureAD提供商文档:
使用服务主体认证时,该资源需要以下应用角色:Policy.ReadWrite.ApplicationConfiguration和Policy.Read.All
使用用户主体认证时,该资源需要以下目录角色之一:应用管理员或全局管理员
我已为该托管标识添加Application Administrator目录角色,但仍出现上述错误;使用Global Administrator角色可成功执行,但希望避免使用该高权限角色。请问是否存在无需全局管理员角色即可部署azuread_claims_mapping_policy的方法?
以下是我使用的代码:
locals { entity_ids = { "dev" : ["entity-id"], } redirect_uris = { "dev" : ["redirect-uri"], } } data "azuread_client_config" "current" {} resource "azuread_application" "saml_integration" { count = var.env == "prod" ? 0 : 1 display_name = "SAML integration - ${upper(var.env)}" owners = [data.azuread_client_config.current.object_id] identifier_uris = local.entity_ids[var.env] web { redirect_uris = local.redirect_uris[var.env] } feature_tags { enterprise = true gallery = false custom_single_sign_on = true } app_role { allowed_member_types = ["Application", "User"] description = "Default role for standard users used for SAML integration" display_name = "IntegrationUser" enabled = true id = "GUID HERE" value = "IntegrationUser" } } resource "azuread_service_principal" "saml_integration_service_principal" { count = var.env == "prod" ? 0 : 1 application_id = azuread_application.saml_integration[0].application_id app_role_assignment_required = false owners = [data.azuread_client_config.current.object_id] use_existing = true preferred_single_sign_on_mode = "saml" feature_tags { enterprise = true gallery = false custom_single_sign_on = true } } resource "azuread_service_principal_token_signing_certificate" "signing_certificate" { service_principal_id = azuread_service_principal.saml_integration_service_principal[0].id } resource "azuread_service_principal_claims_mapping_policy_assignment" "app" { count = var.env == "prod" ? 0 : 1 claims_mapping_policy_id = azuread_claims_mapping_policy.integration_claims_mapping[0].id service_principal_id = azuread_service_principal.saml_integration_service_principal[0].id } resource "azuread_claims_mapping_policy" "integration_claims_mapping" { count = var.env == "prod" ? 0 : 1 display_name = "Claims Mapping for ${azuread_application.saml_integration[0].display_name}" definition = [ jsonencode( { ... hidden ) ] } resource "azuread_user" "test_user" { count = var.env == "prod" ? 0 : 1 user_principal_name = "test-saml-user-${var.env}@contoso.com" mail = "test-saml-user-${var.env}@contoso.com" display_name = "Test Contoso SSO User ${var.env}" given_name = "Test" surname = "User ${upper(var.env)}" password = "SUBERPASSWORD" } resource "azuread_group" "test_app_users_group" { count = var.env == "prod" ? 0 : 1 display_name = "Test SAML integration - ${upper(var.env)}" owners = [data.azuread_client_config.current.object_id] security_enabled = true members = [ azuread_user.test_user[0].object_id ] } resource "azuread_app_role_assignment" "test_user_group_assignment" { app_role_id = azuread_service_principal.saml_integration_service_principal[0].app_role_ids["IntegrationUser"] principal_object_id = azuread_group.test_app_users_group[0].object_id resource_object_id = azuread_service_principal.saml_integration_service_principal[0].object_id }
注:部分敏感值已隐藏。
可以通过以下方式实现无需全局管理员角色部署azuread_claims_mapping_policy:
1. 为托管标识分配正确的应用角色而非目录角色
你之前添加的Application Administrator是目录角色,但根据文档,服务主体(托管标识属于服务主体)认证时需要的是Microsoft Graph应用角色。需要给托管标识分配以下两个应用权限:
Policy.ReadWrite.ApplicationConfigurationPolicy.Read.All
操作步骤:
- 进入Azure AD门户,找到目标托管标识(企业应用程序 -> 所有应用程序 -> 搜索托管标识名称)
- 切换到「权限」选项卡,点击「添加权限」
- 选择「Microsoft Graph」->「应用权限」
- 搜索并勾选上述两个权限,点击「添加权限」
- 点击「授予管理员同意」完成权限配置
2. 确认托管标识的应用所有者身份生效
你的Terraform代码中已将托管标识设置为应用的所有者(owners = [data.azuread_client_config.current.object_id]),需确认该配置已正确生效。应用所有者身份结合上述应用角色权限,即可满足部署需求。
额外排查点
- 权限授予后需等待数分钟让配置生效,避免立即执行Terraform
- 确认Terraform使用的托管标识与配置权限的标识一致,避免混淆不同环境的资源
- 检查
azuread_claims_mapping_policy的definition格式是否正确,排除语法错误导致的间接权限问题
内容的提问来源于stack exchange,提问作者Krzysztof Madej

