You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为托管标识分配Synapse管理员角色时遭遇403授权错误

Azure Synapse Workspace角色分配403权限错误问题

环境设置

一款带有拒绝分配权限的Marketplace应用,负责向客户订阅部署资源,具体操作如下:

  • 创建Azure Synapse Workspace
  • 创建托管标识(Managed Identity)
  • 为托管标识分配Azure Synapse Workspace的Owner角色
  • 创建托管角色分配更新逻辑的容器应用(Container App)
  • 将托管标识添加至所有资源,确保资源间可互相通信

部署与执行流程

  1. Marketplace应用安装完成后,将C#应用镜像推送至ACR并挂载到Azure Container App中
  2. 应用提供触发Synapse工作区角色分配更新的端点,执行流程:
    • 调用Container App上的端点触发服务逻辑
    • 指定托管标识作为角色分配的身份
    • 通过HttpClient或RoleAssignmentClient执行角色分配操作,两种方式均返回403错误

核心问题

尽管托管标识已被授予Synapse Workspace的Owner角色,理论上具备分配Synapse Administrator等角色的权限,但所有角色分配操作均返回403权限不足错误。

已尝试的排查动作

  • 尝试使用两种权限范围(scope):https://management.azure.com/.default 和 https://dev.azuresynapse.net/

代码示例

HttpClient实现代码

public TokenCredential GetCredential(string tenantId = default)
{
    if (!string.IsNullOrEmpty(tenantId))
    {
        return new DefaultAzureCredential(new DefaultAzureCredentialOptions
        {
            TenantId = tenantId,
        });
    }
    if (string.IsNullOrEmpty(EnvironmentVariables.ManagedIdentityClientId))
    {
        return new DefaultAzureCredential();
    }
    var credential = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = EnvironmentVariables.ManagedIdentityClientId,
            TenantId = EnvironmentVariables.TenantId,
        });
    return credential;
}

private async Task<string> GetAccessTokenAsync(CancellationToken cancellationToken)
{
    var credential = credentialProvider.GetCredential();
    var tokenRequestContext = new TokenRequestContext(
        scopes: new[] { "https://management.azure.com/.default" }
    );
    var tokenRequest = await credential.GetTokenAsync(tokenRequestContext, cancellationToken);
    logger.LogInformation(tokenRequest.Token);
    return tokenRequest.Token;
}

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
string roleId = "6e4bf58a-b8e1-4cc3-bbf9-d73143322b78"; //Azure Synapse Administrator
var requestBody = new
{
    roleId,
    principalId = EnvironmentVariables.ManagedIdentityObjectPrincipalId,
    scope = $"workspaces/{EnvironmentVariables.SynapseWorkspaceName}",
    principalType = "ServicePrincipal"
};
var guid = Guid.NewGuid();
var jsonBody = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
var url = $"https://{EnvironmentVariables.SynapseWorkspaceName}.dev.azuresynapse.net/roleAssignments/{guid}?api-version=2020-12-01";
var response = await httpClient.PutAsync(url, content, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
    Console.WriteLine("Role assignment created successfully.");
}

RoleAssignmentsClient实现代码

public TokenCredential GetCredential(string tenantId = default)
{
    if (!string.IsNullOrEmpty(tenantId))
    {
        return new DefaultAzureCredential(new DefaultAzureCredentialOptions
        {
            TenantId = tenantId,
        });
    }
    if (string.IsNullOrEmpty(EnvironmentVariables.ManagedIdentityClientId))
    {
        return new DefaultAzureCredential();
    }
    var credential = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = EnvironmentVariables.ManagedIdentityClientId,
            TenantId = EnvironmentVariables.TenantId,
        });
    return credential;
}

Guid principalId = new Guid(EnvironmentVariables.ManagedIdentityObjectPrincipalId);
Guid roleId = new Guid("6e4bf58a-b8e1-4cc3-bbf9-d73143322b78"); // Synapse Administrator
string endpointUrl = $"https://{EnvironmentVariables.SynapseWorkspaceName}.dev.azuresynapse.net";
var credential = credentialProvider.GetCredential();
var accessControlClient = new RoleAssignmentsClient(new Uri(endpointUrl), credential);
string roleAssignmentId = Guid.NewGuid().ToString();
string scope = $"workspaces/{EnvironmentVariables.SynapseWorkspaceName}";
var response = await accessControlClient.CreateRoleAssignmentAsync(
    roleId: roleId,
    principalId: principalId,
    scope: scope,
    roleAssignmentId: roleAssignmentId, 
    cancellationToken: cancellationToken);

内容的提问来源于stack exchange,提问作者Adrian Flejszer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:51:09