使用应用ID时,如何在Azure API Manager中正确设置Scope?
我为函数应用添加身份提供商,通过Application ID控制访问权限。在逻辑应用中配置以下HTTP认证时可正常运行:
"HTTP": { "inputs": { "authentication": { "audience": "c0e13b97-14f1-430f-bdba-a9651502e8e4", "type": "ManagedServiceIdentity" }, "method": "GET", "uri": "www.replaced.com/api/get_time" }, "runAfter": {}, "runtimeConfiguration": { "contentTransfer": { "transferMode": "Chunked" } }, "type": "Http" },
随后尝试在Azure API Manager(APIM)中配置使用自身托管身份访问该函数应用,参考文档编写了以下策略:
<authentication-managed-identity resource="AD_application_id" output-token-variable-name="msi-access-token" ignore-error="false" /> <!--Application (client) ID of your own Azure AD Application--> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["msi-access-token"])</value> </set-header>
配置后请求发送失败,跟踪日志报错:
authentication-managed-identity (0.081 ms)
{
"messages": [
null,
"Getting Managed Service Identity token for AD_application_id audience threw exception 'System.InvalidOperationException: [MSAL] Authentication failed for ClientId: 2ea6156a-a72f-4a7e-bbaa-8cb2f1002ad1 Certificate: D6E1D650CAFDC108F524C69055892889F1EEC9F1 AuthorizationUrl: https://login.windows.net/6147eb36-9fd8-4609-b472-1d18921607e3 resourceId: AD_application_id ---> Microsoft.Identity.Client.MsalServiceException: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope AD_application_id/.default is not valid. Trace ID: ad5bd488-f5e2-45e5-8d8c-d20acf1d0c00 Correlation ID: 211218e5-be38-457c-a6ed-0a321426bfeb Timestamp: 2024-09-18 14:03:52Z\r\n at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)\r\n at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)\r\n at Microsoft.Identity.Client.OAuth2.OAuth2Client.d__13`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.OAuth2.TokenClient.d__10.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.Identity.Client.OAuth2.TokenClient.d__10.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.OAuth2.TokenClient.d__4.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__24.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.d__4.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Internal.Requests.RequestBase.<>c__DisplayClass11_1.<b__1>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Utils.StopwatchService.d__4.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__11.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Gateway.Policies.Identity.ActiveDirectory.Msal.MsalAadClient.d__12.MoveNext() in C:__w\1\s\Proxy\Gateway.Policies.Identity\ActiveDirectory\Msal\MsalAadClient.cs:line 115\r\n --- End of inner exception stack trace ---\r\n at Gateway.Policies.Identity.ActiveDirectory.Msal.MsalAadClient.d__12.MoveNext() in C:__w\1\s\Proxy\Gateway.Policies.Identity\ActiveDirectory\Msal\MsalAadClient.cs:line 147\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Configuration.Models.ManagedIdentityResolver.d__16.MoveNext() in C:__w\1\s\Proxy\Gateway.Policies.Identity\ManagedIdentityResolver.cs:line 134'.",
"[MSAL] Authentication failed for ClientId: 2ea6156a-a72f-4a7e-bbaa-8cb2f1002ad1 Certificate: D6E1D650CAFDC108F524C69055892889F1EEC9F1 AuthorizationUrl: https://login.windows.net/6147eb36-9fd8-4609-b472-1d18921607e3 resourceId: AD_application_id",
"AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope AD_application_id/.default is not valid. Trace ID: ad5bd488-f5e2-45e5-8d8c-d20acf1d0c00 Correlation ID: 211218e5-be38-457c-a6ed-0a321426bfeb Timestamp: 2024-09-18 14:03:52Z"
]
}
不清楚如何查找和设置正确的Scope,求解决方法。
错误原因
APIM的authentication-managed-identity策略中,直接使用应用程序的Client ID作为resource值时,AAD会自动生成{client-id}/.default的Scope,而这个格式是无效的。正确的做法是使用目标应用的**应用程序ID URI(Application ID URI)**作为resource参数。
逻辑应用能正常运行是因为其MSI实现会自动将Client ID映射为对应的应用程序ID URI,但APIM策略需要显式指定。
解决步骤
获取目标应用的应用程序ID URI
前往Azure AD的「应用注册」,找到函数应用关联的身份提供商应用,在「概述」页面中查看「应用程序ID URI」,格式通常为api://{client-id}(比如你逻辑应用中audience的值对应的URI就是api://c0e13b97-14f1-430f-bdba-a9651502e8e4),也可能是自定义的URI。修改APIM策略
将策略中的resource值替换为上述应用程序ID URI:<authentication-managed-identity resource="api://c0e13b97-14f1-430f-bdba-a9651502e8e4" output-token-variable-name="msi-access-token" ignore-error="false" /> <!--Application ID URI of the target Azure AD Application--> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["msi-access-token"])</value> </set-header>验证效果
修改后,APIM会请求{应用程序ID URI}/.default这个有效的Scope,AAD会正常返回访问令牌,请求即可成功通过认证。
内容的提问来源于stack exchange,提问作者vrghost

