Skip to content

DeleteBulkStateAsync fails with status Unauthenticated if API token authentication is enabled #1762

@dimancis

Description

@dimancis

Expected Behavior

If API token authentication is enabled in Dapr, calls from the Dapr client via gRPC should work without issues when the token is configured correctly.

Actual Behavior

Calling DeleteBulkStateAsync fails with Status(StatusCode="Unauthenticated", Detail="Unauthorized")

State operation failed: the Dapr endpoint indicated a failure. See InnerException for details.
   at Dapr.Client.DaprClientGrpc.DeleteBulkStateAsync(String storeName, IReadOnlyList`1 items, CancellationToken cancellationToken)
   ...
Status(StatusCode="Unauthenticated", Detail="Unauthorized")
   at Dapr.Client.DaprClientGrpc.DeleteBulkStateAsync(String storeName, IReadOnlyList`1 items, CancellationToken cancellationToken)

Steps to Reproduce the Problem

From my point of view, this is obvious in the source code. In https://github.com/dapr/dotnet-sdk/blob/master/src/Dapr.Client/DaprClientGrpc.cs, methods create a new instance of CallOptions before invoking the client.

For example for DeleteStateAsync (line 1426):

var options = CreateCallOptions(headers: null, cancellationToken);

try
{
    await client.DeleteStateAsync(deleteStateEnvelope, options);
    return true;
}

CreateCallOptions sets the header for Dapr api token-based authentication (line 2285):

private CallOptions CreateCallOptions(Metadata headers, CancellationToken cancellationToken)
{
    var options = new CallOptions(headers: headers ?? new Metadata(), cancellationToken: cancellationToken);

    if (options.Headers != null)
    {
        options.Headers.Add("User-Agent", UserAgent().ToString());

        // add token for dapr api token-based authentication
        if (this.apiTokenHeader is not null)
        {
            options.Headers.Add(this.apiTokenHeader.Value.Key, this.apiTokenHeader.Value.Value);
        }
    }

    return options;
}

However, this is different with DeleteBulkStateAsync (line 1104):

await this.Client.DeleteBulkStateAsync(envelope, cancellationToken: cancellationToken);

In this case, no options are passed.

Environment used while reproducing:

  • AKS with Dapr extension
    • 1.16.3
    • 1.16.9
    • 1.17.2
  • Dapr.Client 1.16.0
  • .NET 8

Release Note

RELEASE NOTE:

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions