简体   繁体   中英

asp.net core 2.x Policy Claims wrong identity

I'm working on using the Policies featured (in conjunction with Windows Auth). What I want to accomplish is simple, I want the user to be both authorized to access the app via windows auth, but limit access to sections of an intranet site using policies. My issue is that when I add the claim, it's being added to System.Security.Claims.ClaimsIdentity , instead of System.Security.Principal.WindowsIdentity. This is an issue because the policy.RequireClaim("MyTotallyCoolPolicyName") only searches the xxPrincipal.WindowsIdentiy. FWIW, the claims data I'm attempting to add comes from a db.

Relevant Code Below: Startup.cs services.AddScoped();

services.AddAuthorization(options =>
{
      options.AddPolicy("SuperUser", policy =>
            {
                   policy.RequireAuthenticatedUser();
                   policy.Requirements.Add(new UserRequirement());
                   policy.RequireClaim("Permission Level");
              });
 });


  services.AddScoped<Data.Interface.IAuthorization, Data.EDL.Authorization>();
  services.AddScoped<IAuthorizationHandler, UserPermissionAuthHandler>();
  services.AddScoped<IClaimsTransformation, ClaimsTransformer>();

ClaimsTransformer.cs

public class ClaimsTransformer : IClaimsTransformation
{
      private IHttpContextAccessor _httpContextAccessor;

public ClaimsTransformer(IHttpContextAccessor httpContext)
{
    _httpContextAccessor = httpContext;
}

public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal p)
{
    var pp = new ClaimsPrincipal();

    p.AddIdentity(new ClaimsIdentity("https://customnamehere.com/claims/permissionclaim", "Permission Level", "1"));

    if(p.Claims.Any(a => a.ValueType.Contains("Permission")))
    {
    }
    return Task.FromResult(p);
   }
 }

and this is what it looks like:

See the two identities there

Is there a way to switch to the other claims when using the RequireClaims? Or am I using it wrong?

Fwiw, I don't need to "Add" a new user to the system. The user already exists. So the UserManager class doesn't apply to me.

Adding controller method:

  [Authorize(AuthenticationSchemes ="Windows", Policy = "SuperUser")]
  public IActionResult About()
        {
              ViewData["Message"] = "Your application description page.";

              return View();
        }

Adding UserRequirement class:

  public class UserRequirement : IAuthorizationRequirement
  {
    public string EmailAddress { get; private set; }
    public string UserName { get; set; }
    public int PermissionID { get; set; }

    public bool HasPermission { get; set; } 

    public bool IsActive { get; set; } = false;
    public string PermissionName { get; set; }
  }

It shouldn't matter to what identity the claims are part of. But the claim types should match as expected.

You can use custom names for claim types like role , name , but you can also use the WIF standards . Just make sure that the types matches. User.IsInRole, etc. expect claims of a certain type.

Take a look at the code below. Notice the ClaimsIdentity. I think that is why your code didn't work.

public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal p)
{
    var id = new ClaimsIdentity("TransformerClaimsMiddleware", 
                  "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", 
                  "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");

    // I don't know what your intention is, but it seems more logical to me to
    // add new claims to the identity, instead of adding the same claim with
    // another type.

    var claims = p.Claims.Where(a => a.ValueType.Contains("Permission")).ToList();

    // Add the claims to the new identity
    claims.ForEach(c => id.AddClaim(new Claim("https://customnamehere.com/claims/permissionclaim", c.Value)));

    p.AddIdentity(id);
    return Task.FromResult(p);
   }
}

Also change this:

RequireClaim("Permission Level")

to

RequireClaim("https://customnamehere.com/claims/permissionclaim")

Please let me know if that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM