Azure Function App使用User-managed identity报400认证失败问题求助
Azure PowerShell函数使用用户分配托管标识报400错误
问题描述
我尝试在自己的函数应用中使用用户分配托管标识,该托管标识在函数部署的资源组级别拥有Contributor访问权限。这是一个PowerShell函数,当前仅包含以下代码:
Write-Host "Hello World"
运行函数时收到如下报错:
2021-10-05T13:34:15Z [Warning] WARNING: Unable to acquire token for tenant 'organizations' with error 'ManagedIdentityCredential authentication failed: Service request failed. Status: 400 (Bad Request) Headers: Date: Tue, 05 Oct 2021 13:34:14 GMT Content-Length: 133 ' 2021-10-05T13:34:16Z [Error] ERROR: ManagedIdentityCredential authentication failed: Service request failed. Status: 400 (Bad Request) Headers: Date: Tue, 05 Oct 2021 13:34:14 GMT Content-Length: 133 Exception : Type : Azure.Identity.AuthenticationFailedException TargetSite : Name : FailWrapAndThrow DeclaringType : Azure.Identity.CredentialDiagnosticScope, Azure.Identity, Version=1.4.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8 MemberType : Method Module : Azure.Identity.dll StackTrace : at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex) at Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken) at Azure.Identity.ManagedIdentityCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) at Microsoft.Azure.PowerShell.Authenticators.MsalAccessTokenAcquirer.GetAccessTokenAsync(String callerClassName, String parametersLog, TokenCredential tokenCredential, TokenRequestContext requestContext, CancellationToken cancellationToken, String tenantId, String userId, String homeAccountId) at Microsoft.Azure.Commands.Common.Authentication.Factories.AuthenticationFactory.Authenticate(IAzureAccount account, IAzureEnvironment environment, String tenant, SecureString password, String promptBehavior, Action`1 promptAction, IAzureTokenCache tokenCache, String resourceId) at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.AcquireAccessToken(IAzureAccount account, IAzureEnvironment environment, String tenantId, SecureString password, String promptBehavior, Action`1 promptAction, String resourceId) at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.ListAccountTenants(IAzureAccount account, IAzureEnvironment environment, SecureString password, String promptBehavior, Action`1 promptAction) at Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient.Login(IAzureAccount account, IAzureEnvironment environment, String tenantId, String subscriptionId, String subscriptionName, SecureString password, Boolean skipValidation, Action`1 promptAction, String name, Boolean shouldPopulateContextList, Int32 maxContextPopulation, String authScope) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass118_2.<ExecuteCmdlet>b__5() at System.Threading.Tasks.Task`1.InnerInvoke() at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj) at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread) --- End of stack trace from previous location where exception was thrown --- at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass118_0.<ExecuteCmdlet>b__1(AzureRmProfile localProfile, RMProfileClient profileClient, String name) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.<>c__DisplayClass126_0.<SetContextWithOverwritePrompt>b__0(AzureRmProfile prof, RMProfileClient client) at Microsoft.Azure.Commands.Profile.Common.AzureContextModificationCmdlet.ModifyContext(Action`2 contextAction) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.SetContextWithOverwritePrompt(Action`3 setContextAction) at Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand.ExecuteCmdlet() at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.<>c__3`1.<ExecuteSynchronouslyOrAsJob>b__3_0(T c) at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.ExecuteSynchronouslyOrAsJob[T](T cmdlet, Action`1 executor) at Microsoft.WindowsAzure.Commands.Utilities.Common.CmdletExtensions.ExecuteSynchronouslyOrAsJob[T](T cmdlet) at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord() Message : ManagedIdentityCredential authentication failed: Service request failed. Status: 400 (Bad Request) Headers: Date: Tue, 05 Oct 2021 13:34:14 GMT Content-Length: 133 InnerException : Type : Azure.RequestFailedException Status : 400 TargetSite : Name : MoveNext DeclaringType : Azure.Identity.ManagedIdentitySource+<HandleResponseAsync>d__10, Azure.Identity, Version=1.4.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8 MemberType : Method Module : Azure.Identity.dll StackTrace : at Azure.Identity.ManagedIdentitySource.HandleResponseAsync(Boolean async, TokenRequestContext context, Response response, CancellationToken cancellationToken) at Azure.Identity.ManagedIdentitySource.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken) at Azure.Identity.ManagedIdentityClient.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken) at Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken) Message : Service request failed. Status: 400 (Bad Request) Headers: Date: Tue, 05 Oct 2021 13:34:14 GMT Content-Length: 133 Source : Azure.Identity HResult : -2146233088 Source : Azure.Identity HResult : -2146233088 CategoryInfo : CloseError: (:) [Connect-AzAccount], AuthenticationFailedException FullyQualifiedErrorId : Microsoft.Azure.Commands.Profile.ConnectAzureRmAccountCommand InvocationInfo : MyCommand : Connect-AzAccount ScriptLineNumber : 16 OffsetInLine : 5 HistoryId : 1 ScriptName : C:\home\site\wwwroot\profile.ps1 Line : Connect-AzAccount -Identity PositionMessage : At C:\home\site\wwwroot\profile.ps1:16 char:5 + Connect-AzAccount -Identity + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ PSScriptRoot : C:\home\site\wwwroot PSCommandPath : C:\home\site\wwwroot\profile.ps1 InvocationName : Connect-AzAccount CommandOrigin : Internal ScriptStackTrace : at <ScriptBlock>, C:\home\site\wwwroot\profile.ps1: line 16 PipelineIterationInfo : 2021-10-05T13:34:17Z [Error] Errors reported while executing profile.ps1. See logs for detailed errors. Profile location: C:\home\site\wwwroot\profile.ps1. 2021-10-05T13:34:17Z [Information] INFORMATION: Hello World
我已按照官方文档中的步骤操作,也二次确认了函数应用确实已设置IDENTITY_ENDPOINT和IDENTITY_HEADER两个环境变量。始终无法解决该问题,但系统分配托管标识可以正常使用。我也尝试过组合使用Connect-AzAccount和Set-AzContext命令,最终都返回相同错误。
解决方案
核心问题是Connect-AzAccount -Identity默认调用系统分配托管标识,未指定用户分配托管标识的唯一标识,导致身份认证请求参数缺失触发400错误,按以下步骤修正即可:
- 修改
profile.ps1中的认证命令,补充-AccountId参数指定要使用的用户分配托管标识,参数值可以填该托管标识的客户端ID、对象ID或资源ID任意一种:
# 替换尖括号内容为你自己的用户分配托管标识客户端ID Connect-AzAccount -Identity -AccountId <用户分配托管标识客户端ID>
- 额外检查项:
- 确认函数应用托管标识配置页中,已正确添加目标用户分配托管标识,状态为启用
- 确认该托管标识的Contributor权限分配范围正确,没有权限阻断规则
- 如果使用的Az.PowerShell模块版本低于6.0,建议升级到最新稳定版规避已知适配问题
内容的提问来源于stack exchange,提问作者Radfd13
相关产品推荐
相关产品推荐

