Custom Authorization Policy User.Identity.Name is null

20 Views Asked by At

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.

0

There are 0 best solutions below