I created a new “ASP.NET Core Web API” project.
In Program.cs I configured authentication and authorization as follows:
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddSingleton<IAuthorizationHandler, CanGetWeatherAuthorizationHandler>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("CanGetWeather", policy =>
policy.Requirements.Add(new CanGetWeatherRequirement()));
});
I don’t think they are relevant to the issue, but here is CanGetWeatherRequirement.cs:
public class CanGetWeatherRequirement : IAuthorizationRequirement
{
}
and CanGetWeatherAuthorizationHandler.cs:
public class CanGetWeatherAuthorizationHandler() : AuthorizationHandler<CanGetWeatherRequirement>
{
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CanGetWeatherRequirement requirement
)
{
var userId = context.User.Identities.First();
if (userId.IsAuthenticated)
{
if (await UserCanGetWeatherAsync())
context.Succeed(requirement);
}
}
private static async Task<bool> UserCanGetWeatherAsync() =>
await Task.Run(() => Random.Shared.NextDouble() > 0.5);
}
I expected, when sending a GET request to the WeatherForecast endpoint, that the HandleRequirementAsync method will be called once with the context containing an authenticated user ID (context.User.Identities.First().IsAuthenticated == true
).
Instead it is being called twice
- The first time context.User.Identities.First().IsAuthenticated is false
- The second time context.User.Identities.First().IsAuthenticated is true