I am changing an API to use windows Authentication with (NegotiateDefaults.AuthenticationSheme).AddNegotiatie()
I created a custom policy so that the user allowed to use the API will change depending on the environment.
builder.Services
.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
options.AddPolicy("ConfigRole", policy =>
policy.Requirements.Add(new ConfigRoleRequirement(builder.Configuration.GetSection("ConfigIISRole").Value)));
});
Here is the requirement.
public class ConfigRoleRequirement : IAuthorizationRequirement
{
public ConfigRoleRequirement(string configValue)
{
AuthenticatedIISUser = configValue;
}
public string AuthenticatedIISUser { get; }
}
Here is the requirement handler
public class ConfigRoleRequirementHandler : AuthorizationHandler<ConfigRoleRequirement>
{
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context, ConfigRoleRequirement requirement)
{
var userNameClaim = context.User.Identity.Name;
if(userNameClaim == null)
{
return Task.CompletedTask;
}
if (userNameClaim == requirement.AuthenticatedIISUser)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
This is where userNameClaim is null. The interesting thing is that if I don't use the custom policy but just annotate my endpoint with (Roles = "DOMAIN\USER") it authenticates as expected. What is the difference between how the Roles argument to the Authorize annotation handles authentication and what I am doing?
Here is the controller annotation
[HttpGet("{arg}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = "ConfigRole")]
public async Task<ActionResult<List<ValidateArg>>> ValidateArg(string arg)
{
var containers = await ValidateArg(arg);
return Ok(containers);
}
I have read any article or question on stackoverflow that I could find and though they seem related at first glance, the answers never seem to apply to what my code is doing specifically.