Skip to content

Endpoint with AllowAnonymous() returns 401 when API version is unsupported or unspecified #1131

@naegelejd

Description

@naegelejd

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I am using Minimal APIs with Asp.Versioning.Mvc 8.1.0.

I have Authentication and Authorization enabled with default JWT-Bearer Authentication scheme and default Authorization policy (the only requirement is DenyAnonymousAuthorizationRequirement).

As expected, with Authentication/Authorization disabled, I get a 400 Bad Request response when I provide an invalid API version in a client request (or omit the API version altogether).

However, if I enable Authentication/Authorization, and use .AllowAnonymous() to bypass the authorization requirement on an endpoint, I get a 401 Unauthorized response for the same requests.

Is this the expected behavior? Either way, is there a way to work around this so that we can return a 401 response?

Expected Behavior

When I use .AllowAnonymous() on an endpoint, I expect to receive a 401 Bad Request when a client request omits the API version or provides an invalid API version.

Steps To Reproduce

Minimal server to reproduce:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Asp.Versioning;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication().AddJwtBearer();

builder.Services.AddAuthorization();
builder.Services.AddOptions<AuthorizationOptions>().Configure((authOptions) =>
{
    authOptions.FallbackPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
});


builder.Services.AddApiVersioning(options =>
{
    options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

var api = app.NewVersionedApi();
api.MapGet("/foo", () => "Hello World!").AllowAnonymous().HasApiVersion(1.0);

app.Run();

Demo:

$ curl -i http://localhost:5080/foo?api-version=1.0
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 22 Apr 2025 20:49:15 GMT
Server: Kestrel
Transfer-Encoding: chunked

$ curl -i http://localhost:5080/foo?api-version=1.1
HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Tue, 22 Apr 2025 20:49:18 GMT
Server: Kestrel
WWW-Authenticate: Bearer

$ curl -i http://localhost:5080/foo
HTTP/1.1 401 Unauthorized
Content-Length: 0
Date: Tue, 22 Apr 2025 20:49:29 GMT
Server: Kestrel
WWW-Authenticate: Bearer

Exceptions (if any)

No response

.NET Version

9.0.102

Anything else?

No response

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions