2021-07-29

Can't access secure endpoint under a policy (authorization in general works) in Identity Server 4

In Startup.cs of my API, I have the following authorization policies.

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllers();
  services.AddAuthentication(...);
  ...
  services.AddAuthorization(options =>
  {
      options.AddPolicy("VerySecurePolicy", policy =>
      {
          policy.RequireClaim("admin");
      });
      options.AddPolicy("VaguelySecurePolicy", policy =>
      {
          policy.RequireAuthenticatedUser();
      });
  });
}

Then, I protect two action methods, one with parameterless attribute and one with a policy specified.

[Authorize, HttpGet("regular")]
public IActionResult GetRegularData() { return Ok("This is regular level data."); }

[Authorize(Policy = "VerySecurePolicy"), HttpGet("admin")]
public IActionResult GetAdminData() { return Ok("This is admin level data."); }

After login, I can access the former but not the latter. My deduction is that the claim admin isn't assigned properly on my user and I can't see what I'm missing. Checking the user info endpoint (/connect/userinfo) with my access token gives me the ID, email etc. but not the role admin. Inspecting token itself shows no claims array at all (only scopes and the usual claims like sub, exp etc.).

This is the TestUser instance logged in.

yield return new TestUser
{
    SubjectId = "37cfad39-e4da-486b-a8db-a752565125f8", ...
    Claims = new List<Claim>
    {
        new Claim(JwtClaimTypes.Email, "fakey.uno@touchtech.comm"), ...
        new Claim(JwtClaimTypes.Role, "admin")
    }
};

One of the API scopes declared contains admin as a claim. I've verified that scope to be in the access token. I also added info in an API resource like so (although I'm not sure it's actually needed for this).

yield return new ApiScope("test_scope_a1", "Test scope A1", new[] { "admin" });

yield return new ApiResource
{
    ...
    Scopes = new List<string> { "test_scope_a1", ... },
    UserClaims = new List<string> { "admin", ... }
};

Proof of effort:



from Recent Questions - Stack Overflow https://ift.tt/3BPvdwP
https://ift.tt/eA8V8J

No comments:

Post a Comment