Azure 数字孪生 API 无法使用教程中所述的 DefaultAzureCredential 身份验证方法

Posted

技术标签:

【中文标题】Azure 数字孪生 API 无法使用教程中所述的 DefaultAzureCredential 身份验证方法【英文标题】:Azure Digital Twins APIs is not working with DefaultAzureCredential authentication method as described in the tutorial 【发布时间】:2021-04-22 17:11:16 【问题描述】:

我在关注Coding with the Azure Digital Twins APIs tutorial。如tutorial 所述,我准备了一个 Azure 数字孪生实例。这是我的职责 -

这是我的 Azure 数字孪生实例 -

这是我的访问权限 -

DefaultAzureCredential 方法

然后,我按照tutorial 的描述设置了本地 Azure 凭据。我已通过 Azure CLI 和 VS Code extension 登录到 Azure。

但是当我按照tutorial 的指示上传模型时,我收到了 Azure.Identity.AuthenticationFailedException 错误。这是我的客户端应用程序的代码 -

代码

using System;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;

namespace ADT_demo

    class Program
    
        static async Task Main(string[] args)
        
            string adtInstanceUrl = "https://digitaltwinsek3p.api.wcus.digitaltwins.azure.net";

            var credential = new DefaultAzureCredential();
            DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
            Console.WriteLine($"Service client created – ready to go");



            Console.WriteLine();
            Console.WriteLine($"Upload a model");
            var typeList = new List<string>();
            string dtdl = File.ReadAllText("SampleModel.json");
            typeList.Add(dtdl);
            // Upload the model to the service
            await client.CreateModelsAsync(typeList);

            Console.WriteLine("Hello World!");
        
    


错误

Unhandled exception. Azure.Identity.AuthenticationFailedException: SharedTokenCacheCredential authentication failed: A configuration issue is preventing authentication - check the error message from the server for details.You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details.  Original exception: AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
Trace ID: 9e17bbaa-e120-4d31-af90-121216db0c00
Correlation ID: c2cf4df0-5257-4de6-892c-66855072ad95
Timestamp: 2021-01-18 11:17:11Z
 ---> MSAL.NetCore.4.22.0.0.MsalServiceException:
        ErrorCode: invalid_client
Microsoft.Identity.Client.MsalServiceException: A configuration issue is preventing authentication - check the error message from the server for details.You can modify the configuration in the application registration portal. See https://aka.ms/msal-net-invalid-client for details.  Original exception: AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
Trace ID: 9e17bbaa-e120-4d31-af90-121216db0c00
Correlation ID: c2cf4df0-5257-4de6-892c-66855072ad95
Timestamp: 2021-01-18 11:17:11Z
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(String tokenEndpoint, IDictionary`2 additionalBodyParameters, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.CacheSilentStrategy.RefreshAccessTokenAsync(MsalRefreshTokenCacheItem msalRefreshTokenItem, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.CacheSilentStrategy.TryGetTokenUsingFociAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.CacheSilentStrategy.RefreshRtOrFailAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.CacheSilentStrategy.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.CacheSilentStrategy.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.ApiConfig.Executors.ClientApplicationBaseExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenSilentParameters silentParameters, CancellationToken cancellationToken)
   at Azure.Identity.AbstractAcquireTokenParameterBuilderExtensions.ExecuteAsync[T](AbstractAcquireTokenParameterBuilder`1 builder, Boolean async, CancellationToken cancellationToken)
   at Azure.Identity.MsalPublicClient.AcquireTokenSilentAsync(String[] scopes, IAccount account, Boolean async, CancellationToken cancellationToken)
   at Azure.Identity.SharedTokenCacheCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
        StatusCode: 401
        ResponseBody: "error":"invalid_client","error_description":"AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.\r\nTrace ID: 9e17bbaa-e120-4d31-af90-121216db0c00\r\nCorrelation ID: c2cf4df0-5257-4de6-892c-66855072ad95\r\nTimestamp: 2021-01-18 11:17:11Z","error_codes":[70002],"timestamp":"2021-01-18 11:17:11Z","trace_id":"9e17bbaa-e120-4d31-af90-121216db0c00","correlation_id":"c2cf4df0-5257-4de6-892c-66855072ad95","error_uri":"https://login.microsoftonline.com/error?code=70002"
        Headers: Cache-Control: no-store, no-cache
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
client-request-id: c2cf4df0-5257-4de6-892c-66855072ad95
x-ms-request-id: 9e17bbaa-e120-4d31-af90-121216db0c00
x-ms-ests-server: 2.1.11397.13 - KRSLR2 ProdSlices
x-ms-clitelem: 1,70002,0,99387912.9884,
Set-Cookie: fpc=AgEOOZYkMXtLt3KqlIDdhsj8dx2YAQAAADdll9cOAAAA; expires=Wed, 17-Feb-2021 11:17:11 GMT; path=/; secure; HttpOnly; SameSite=None,x-ms-gateway-slice=prod; path=/; secure; samesite=none; httponly,stsservicecookie=estsfd; path=/; secure; samesite=none; httponly
Date: Mon, 18 Jan 2021 11:17:11 GMT

   --- End of inner exception stack trace ---
   at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex)
   at Azure.Identity.SharedTokenCacheCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
   at Azure.Identity.SharedTokenCacheCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
   at Azure.Identity.DefaultAzureCredential.GetTokenFromSourcesAsync(TokenCredential[] sources, TokenRequestContext requestContext, Boolean async, CancellationToken cancellationToken)
   at Azure.Identity.DefaultAzureCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
   at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex)
   at Azure.Identity.DefaultAzureCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
   at Azure.Identity.DefaultAzureCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
   at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.AccessTokenCache.GetHeaderValueFromCredentialAsync(HttpMessage message, Boolean async, CancellationToken cancellationToken)
   at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.AccessTokenCache.GetHeaderValueAsync(HttpMessage message, Boolean async)
   at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.ProcessAsync(HttpMessage message, ReadOnlyMemory`1 pipeline, Boolean async)
   at Azure.Core.Pipeline.HttpPipelineSynchronousPolicy.ProcessAsync(HttpMessage message, ReadOnlyMemory`1 pipeline)
   at Azure.DigitalTwins.Core.DigitalTwinModelsRestClient.AddAsync(IEnumerable`1 models, CreateModelsOptions digitalTwinModelsAddOptions, CancellationToken cancellationToken)
   at Azure.DigitalTwins.Core.DigitalTwinsClient.CreateModelsAsync(IEnumerable`1 dtdlModels, CancellationToken cancellationToken)
   at ADT_demo.Program.Main(String[] args) in C:\Users\<location>\Program.cs:line 29
   at ADT_demo.Program.<Main>(String[] args)

InteractiveBrowserCredential 方法

但是,当我使用InteractiveBrowserCredential method 并通过应用注册 获得 Azure 数字孪生 API 的权限时,它运行良好。

代码

using System;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.Threading.Tasks;
using System.IO;
using System.Collections.Generic;
using Azure;

namespace ADT_demo

    class Program
    
        static async Task Main(string[] args)
        
            string adtInstanceUrl = "https://digitaltwinsek3p.api.wcus.digitaltwins.azure.net";
            string clientId = "<your-client-ID>";
            string tenantId = "<your-tenant-ID>";

            var credential = new InteractiveBrowserCredential(tenantId, clientId);
            DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
            Console.WriteLine($"Service client created – ready to go");


            Console.WriteLine();
            Console.WriteLine($"Upload a model");
            var typeList = new List<string>();
            string dtdl = File.ReadAllText("SampleModel.json");
            typeList.Add(dtdl);
            // Upload the model to the service
            await client.CreateModelsAsync(typeList);

            Console.WriteLine("Hello World!");
        
    

为什么身份验证在 DefaultAzureCredential 方法中不起作用?

【问题讨论】:

【参考方案1】:

documentation 声明 DefaultAzureCredential 只是一个按顺序尝试的包装器:

EnvironmentCredential
ManagedIdentityCredential
SharedTokenCacheCredential
VisualStudioCredential
VisualStudioCodeCredential
AzureCliCredential
InteractiveBrowserCredential

如您所见,在尝试使用 Visual Studio 代码凭据或 azure CLI 凭据之前,将使用共享令牌凭据(产生异常的凭据)。

因此,简单的解决方法是将DefaultAzureCredential 替换为例如AzureCliCredential。长期的解决办法是等待其他人解释共享令牌凭证条目的存储位置,然后删除它们或更新它们。

【讨论】:

我相信 OP 遇到的问题是 SharedTokenCacheCredential 的一个已知问题。他们可以使用 var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions ExcludeSharedTokenCacheCredential = true ); 的选项从 DefaultAzureCredential 中排除此凭据。

以上是关于Azure 数字孪生 API 无法使用教程中所述的 DefaultAzureCredential 身份验证方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用逻辑应用修改 Azure 分析服务角色?

将 Azure 数字孪生与现有云环境连接

Azure 数字孪生 - 计算模型数量

我的帐户未启用到 Firebase 的数字迁移

DTDL - 如何在 Azure 数字孪生模型中对电梯间及其在楼层之间的移动进行建模?

mysql数据库02 基础教程