christok
christok

Reputation: 1107

aspnet core 2.0 policy-based authorization keeps returning 403

I'm trying to implement a policy=based authentication scheme using Windows Authentication and custom claims. Everything compiles and runs OK but authorization keeps failing due to unknown reasons. Here's what I'm doing:

1 - in startup.cs, we add windows auth as authentication scheme, add a "BASIC_USER" policy requiring "BASIC_USER" claim, and inject a claims transformer.

public void ConfigureServices(IServiceCollection services)
{

  services.AddMvc();

  services.AddTransient<IClaimsTransformation, ClaimsTransformer>();

  services.AddAuthentication(IISDefaults.AuthenticationScheme);

  services.AddAuthorization(options =>
  {
    options.AddPolicy("BASIC_USER", policy => policy.RequireClaim("BASIC_USER"));
  });

}

2 - our claims transformer adds the claim to the ClaimsPrincipal on each request. (Normally this would add claims based on data-driven roles but edited for brevity.)

public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{

    Claim claim = new Claim(ClaimTypes.Role, "BASIC_USER");

    ((ClaimsIdentity)principal.Identity)
        .AddClaim(claim);

    return await Task.FromResult(principal);

  }

}

3 - We decorate our controller with Authorize attribute:

  public class MyController : Controller
  {

    [Authorize(Policy = "BASIC_USER")]
    public async Task<ActionResult> Get()
    {
      ...
    }
  }

When I step #1 and #2 above everything seems to be in order - the policy is added at startup and the claim is added on the request, but still the controller returns a properly-formed 403. Is there a way to debug the authorization process or am I missing something obvious here?

Upvotes: 0

Views: 481

Answers (1)

christok
christok

Reputation: 1107

This turned out to be caused by a small oversight. This line:

options.AddPolicy("BASIC_USER", policy => policy.RequireClaim("BASIC_USER"));

Should actually read:

options.AddPolicy("BASIC_USER", policy => policy.RequireClaim(ClaimTypes.Role, "BASIC_USER"));

The claim type must match that which is added to the principal in TransformAsync.

Upvotes: 1

Related Questions