Насколько я могу сказать, что вы ищете, чтобы создать SignInManager
в ConfigureServices
методе Startup.cs
класса как так:
services.AddScoped<SignInManager<ApplicationUser>, AvantiaSignInManager<ApplicationUser>>();
Затем вы можете реализовать свой собственный SignInManager
как следующее:
public class AvantiaSignInManager<TUser> : SignInManager<TUser> where TUser : class
Вы должны реализовать 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;
}
Затем я создал 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;
}
Это позволит мне, из любого xxxController унаследовав от моего BaseController
делать такие вещи, как:
model.EmployeeID = UsersEmployeeID;
Я понимаю, что прошло несколько месяцев с тех пор, как вы задали этот вопрос, но для вас и любого, кто приходит к этому после этого факта, надеюсь, что это поможет.
Я не понимаю, как ваш ответ относится к поддержке токенов-антикоррозий? –
Приношу свои извинения. Я думал, что вы действительно просто хотите, чтобы кто-то удостоверился в уникальном пользователе. – Grandizer