ASP.NET Core 中的 AntiForgeryConfig.UniqueClaimTypeIdentifier

Jon*_*nas 5 asp.net-core

在 ASP.NET 的早期版本中,我们通常使用名为AntiForgeryConfig.UniqueClaimTypeIdentifier的属性进行基于声明的授权,以根据用于唯一标识用户的身份设置声明类型。

在 ASP.NET Core 中这是如何完成的?

Gra*_*zer -3

SignInManager据我所知,您正在寻找的内容是在Startup.cs类的方法中设置 a ,ConfigureServices如下所示:

services.AddScoped<SignInManager<ApplicationUser>, AvantiaSignInManager<ApplicationUser>>();
Run Code Online (Sandbox Code Playgroud)

SignInManager然后你可以像下面这样实现你自己的:

public class AvantiaSignInManager<TUser> : SignInManager<TUser> where TUser : class
Run Code Online (Sandbox Code Playgroud)

您必须实现CreateUserPrincipalAsync如下所示的方法:

public override async Task<ClaimsPrincipal> CreateUserPrincipalAsync(TUser user) {
  var Principal = await base.CreateUserPrincipalAsync(user);
  var Identity = (ClaimsIdentity)Principal.Identity;

  // How To: Here is where you can add Custom/On the fly Claims
  // They would not be persisted in the database but are within the Cookie

  var Employee = _dataContext.Employees
    .Include(x => x.Tenant)
    .ThenInclude(x => x.Subscriber)
    .Where(x => x.Email == Identity.Name)
    .SingleOrDefault();

  // See if there are any Claims linked to this user
  var MyClaims = _dataContext.EmployeeRoleClaims
    .Where(x => x.EmployeeID == Employee.ID)
    .Select(x => x.RoleClaim)
    .ToList();

  if (Employee != null) {
    // Add common Claims for every user, but the values are unique to them
    Identity.AddClaim(new Claim(Constants.Claims.Employee.ID, Employee.ID.ToString()));
    Identity.AddClaim(new Claim(Constants.Claims.Employee.Number, Employee.Number));
    Identity.AddClaim(new Claim(Constants.Claims.Tenant.ID, Employee.TenantID.ToString()));
    Identity.AddClaim(new Claim(Constants.Claims.Tenant.Name, Employee?.Tenant.Name));
    Identity.AddClaim(new Claim(Constants.Claims.Subscriber.ID, Employee?.Tenant.SubscriberID.ToString()));
    Identity.AddClaim(new Claim(Constants.Claims.Subscriber.Name, Employee?.Tenant?.Subscriber.Name));

    // Add any special Claims - May not be necessary within your application
    foreach (var rc in MyClaims) {
      Identity.AddClaim(rc.ToClaim()); // Add the Claim normally

      if ((rc.ClaimType == Constants.Claims.Subscriber.Administrator) ||
        (rc.ClaimType == Constants.Claims.Subscriber.TimeSheetAdmin) ||
        (rc.ClaimType == Constants.Claims.Subscriber.TimeSheetReview)) {
        var myTenants = _dataContext.Tenants.Where(x => x.SubscriberID == Convert.ToInt64(rc.ClaimValue)).ToList();

        foreach (var t in myTenants) {
          if (rc.ClaimType == Constants.Claims.Subscriber.Administrator)
            Identity.AddClaim(new Claim(Constants.Claims.Tenant.Administrator, t.ID.ToString()));
          else if (rc.ClaimType == Constants.Claims.Subscriber.TimeSheetAdmin)
            Identity.AddClaim(new Claim(Constants.Claims.Tenant.TimeSheetAdmin, t.ID.ToString()));
          else if (rc.ClaimType == Constants.Claims.Subscriber.TimeSheetReview)
            Identity.AddClaim(new Claim(Constants.Claims.Tenant.TimeSheetReview, t.ID.ToString()));
        } // foreach of the Tenants within the Subscription
      } // if I am the Administrator of a Subscription, I should also get the Tenants as well
    } // foreach of the Claims that have been specifically assinged to me

    // Add Claims for each of the Projects I am a Manager of or a Member of
    var PM = _dataContext.ProjectRoles.Where(x => x.Name == "Project Manager").FirstOrDefault();

    if (PM != null) {
      // Get the Projects where I am the Project Manager
      var MyPMProjects = _dataContext.ProjectProjectRoleEmployees.Where(x => x.EmployeeID == Employee.ID && x.ProjectRoleID == PM.ID).ToList();

      foreach(var Project in MyPMProjects)
        Identity.AddClaim(new Claim(Constants.Claims.Project.ManagerOf, Project.ProjectID.ToString()));

      // Get the Projects that I am ON but am NOT the Project Manager
      var MyProjects = _dataContext.ProjectProjectRoleEmployees.Where(x => x.EmployeeID == Employee.ID && x.ProjectRoleID != PM.ID).ToList();

      foreach (var Project in MyProjects)
        Identity.AddClaim(new Claim(Constants.Claims.Project.MemberOf, Project.ProjectID.ToString()));
    } // if we found the Project Manager Role
  } // if we found the associated Employee record

  return Principal;
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个BaseController覆盖默认Controller类的类:

public class BaseController : Controller {

  internal ILogger logger;

  public string UsersLoginName => User.Identity.Name;
  public long UsersEmployeeID => User.HasClaim(x => x.Type == Constants.Claims.Employee.ID) ? Convert.ToInt64(User.FindFirst(Constants.Claims.Employee.ID).Value) : 0;
  public long UsersTenantID => User.HasClaim(x => x.Type == Constants.Claims.Tenant.ID) ? Convert.ToInt64(User.FindFirst(Constants.Claims.Tenant.ID).Value) : 0;
  public long UsersSubscriberID => User.HasClaim(x => x.Type == Constants.Claims.Subscriber.ID) ? Convert.ToInt64(User.FindFirst(Constants.Claims.Subscriber.ID).Value) : 0;

}
Run Code Online (Sandbox Code Playgroud)

这将允许我从任何继承自 my 的 xxxControllerBaseController执行以下操作:

model.EmployeeID = UsersEmployeeID;
Run Code Online (Sandbox Code Playgroud)

我知道你问这个问题已经有几个月了,但对于你和任何事后提出这个问题的人来说,希望它能对你有所帮助。