asp.net core 2.x策略声称身份错误

时间:2018-11-01 15:19:05

标签: c# .net asp.net-core claims-based-identity asp.net-core-identity

我正在使用“策略”功能(与Windows Auth结合使用)。我想要完成的事情很简单,我希望用户既被授权通过Windows Auth访问应用程序,又要使用策略限制对Intranet网站部分的访问。我的问题是,当我添加声明时,它被添加到 System.Security.Claims.ClaimsIdentity 中,而不是 System.Security.Principal.WindowsIdentity。因为 policy.RequireClaim(“ MyTotallyCoolPolicyName”)仅搜索xxPrincipal.WindowsIdentiy。 FWIW,我尝试添加的索赔数据来自数据库。

以下相关代码: 启动文件     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);
   }
 }

这是它的样子:

See the two identities there

使用RequireClaims时是否可以切换到其他声明?还是我使用错了?

首先,我不需要将新用户“添加”到系统中。用户已经存在。因此UserManager类不适用于我。

添加控制器方法:

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

              return View();
        }

添加UserRequirement类:

  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; }
  }

1 个答案:

答案 0 :(得分:0)

声明所属于的身份无关紧要。但是声明类型应符合预期。

您可以对诸如rolename之类的声明类型使用自定义名称,但也可以使用WIF standards。只要确保类型匹配即可。 User.IsInRole等需要某种类型的声明。

看看下面的代码。请注意ClaimsIdentity。我认为这就是为什么您的代码无法正常工作的原因。

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);
   }
}

还要更改此内容:

RequireClaim("Permission Level")

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

请告诉我是否有帮助。