Microsoft.Extensions.Caching.Cosmos.CosmosCache 不适用于 MSAL 令牌

Microsoft.Extensions.Caching.Cosmos.CosmosCache not working for MSAL tokens

我收到以下错误。我正在尝试将 Cosmos 配置为 MSAL 的缓存。

The input ttl 'null' is invalid. Ensure to provide a nonzero positive integer less than or equal to '2147483647', or '-1' which means never expire.

完整错误:

Response status code does not indicate success: 400 Substatus: 0 Reason: (Microsoft.Azure.Documents.BadRequestException: Message: {"Errors":["The input ttl 'null' is invalid. Ensure to provide a nonzero positive integer less than or equal to '2147483647', or '-1' which means never expire."]}ActivityId: ee10ce6b-bc78-4b64-a874-d464c2db1712, Request URI: /apps/9610078f-64d0-4c3a-8746-3fe6f02be78f/services/c5612d1f-a656-4cf5-99c4-0b1f50b5a1e2/partitions/2107c960-b060-49d1-8e03-3939fc11bb8a/replicas/132575139009767109p/, RequestStats: RequestStartTime: 2021-02-15T10:10:06.2053638Z, RequestEndTime: 2021-02-15T10:10:06.3804622Z, Number of regions attempted:1ResponseTime: 2021-02-15T10:10:06.3804622Z, StoreResult: StorePhysicalAddress: rntbd://cdb-ms-prod-westeurope1-fd56.documents.azure.com:14056/apps/9610078f-64d0-4c3a-8746-3fe6f02be78f/services/c5612d1f-a656-4cf5-99c4-0b1f50b5a1e2/partitions/2107c960-b060-49d1-8e03-3939fc11bb8a/replicas/132575139009767109p/, LSN: 3, GlobalCommittedLsn: 3, PartitionKeyRangeId: 0, IsValid: True, StatusCode: 400, SubStatusCode: 0, RequestCharge: 2.38, ItemLSN: -1, SessionToken: -1#3, UsingLocalLSN: False, TransportException: null, ResourceType: Document, OperationType: Upsert, SDK: Windows/10.0.19042 cosmos-netstandard-sdk/3.4.2 at Microsoft.Azure.Documents.TransportClient.ThrowServerException(String resourceAddress, StoreResponse storeResponse, Uri physicalAddress, Guid activityId, DocumentServiceRequest request) at Microsoft.Azure.Documents.Rntbd.TransportClient.<InvokeStoreAsync>d__8.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Azure.Documents.ConsistencyWriter.<WritePrivateAsync>d__17.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.BackoffRetryUtility1.d__5.MoveNext()--- End of stack trace from previous location where exception was thrown --- at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying(ExceptionDispatchInfo capturedException) at Microsoft.Azure.Documents.BackoffRetryUtility1.<ExecuteRetryAsync>d__5.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.ConsistencyWriter.<WriteAsync>d__16.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.ReplicatedResourceClient.<>c__DisplayClass26_0.<<InvokeAsync>b__0>d.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Microsoft.Azure.Documents.RequestRetryUtility.<ProcessRequestAsync>d__22.MoveNext()--- End of stack trace from previous location where exception was thrown --- at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying(ExceptionDispatchInfo capturedException) at Microsoft.Azure.Documents.RequestRetryUtility.d__22.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.StoreClient.<ProcessMessageAsync>d__19.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.ServerStoreModel.<ProcessMessageAsync>d__15.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Cosmos.Handlers.TransportHandler.<ProcessUpsertAsync>d__5.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Cosmos.Handlers.TransportHandler.<SendAsync>d__2.MoveNext()).

此代码似乎有效:

 public IConfidentialClientApplication BuildApp()
    {
        // The application which retreives the auth token must also use the same client id and redirect url when requesting the token. The auth token from the response is then passed to the AquireTokenByAuthorisationCode method below. 
        IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
            .Create("XXX")
            .WithRedirectUri("XXX")
            .WithClientSecret("XXX")
            .WithTenantId("XXX")
            .Build();

        IMsalTokenCacheProvider cosmosTokenCacheProvider = CreateCosmosTokenCacheSerialiser();
        Task.Run(() => cosmosTokenCacheProvider.InitializeAsync(app.UserTokenCache)).Wait();

        return app;
    }

private static IMsalTokenCacheProvider CreateCosmosTokenCacheSerialiser()
    {
        IServiceCollection services = new ServiceCollection();

        services.AddDistributedTokenCaches();
        services.AddCosmosCache((CosmosCacheOptions cacheOptions) =>
        {
            cacheOptions.DatabaseName = ConfigurationManager.AppSettings["XXX"];
            cacheOptions.ContainerName = ConfigurationManager.AppSettings["XXX"];
            cacheOptions.CreateIfNotExists = true;
            cacheOptions.ClientBuilder = new CosmosClientBuilder(cosmosConnectionString);
            //cacheOptions.DefaultTimeToLiveInMs = 100000;
        });

        IServiceProvider serviceProvider = services.BuildServiceProvider();
        IMsalTokenCacheProvider msalTokenCacheProvider = serviceProvider.GetRequiredService<IMsalTokenCacheProvider>();

        return msalTokenCacheProvider;
    }

但是当运行这个时候流程失败:

       public async Task AquireTokenByAuthorisationCode(IEnumerable<string> scopes, string authorisationCode)
    {


        var authenticationResult = await _confidentialClientApplication.AcquireTokenByAuthorizationCode(scopes, authorisationCode).ExecuteAsync();
    }

我尝试了各种设置组合 cacheOptions.DefaultTimeToLiveInMs 并尝试在 Cosmos 容器级别打开和关闭 ttl。

我是不是配置有误或者这是个问题?

谢谢, 汤姆

根据错误跟踪,您使用的版本似乎很旧:Windows/10.0.19042 cosmos-netstandard-sdk/3.4.2

当前的 Nuget 包 (preview-5) 需要 SDK >= 3.11.0。

能否请您尝试将 Nuget 包更新到最新的 preview-5 版本?