Настройка простого контроля доступа на основе ролей на уровне действий в MVC 5
Я считаю, что я увлекся этим: безопасность на основе ролей в многоуровневом проекте на основе MVC является для меня чем-то неизвестным. Мне трудно понять, как можно сопоставить пользователя с Controller
и что более важно, Action
, Я просмотрел общее описание, которое было дано мне ниже (поддельный PII):
Исходя из этого, мне удалось придумать такую структуру данных, которая кажется немного перегруженной:
Таблицы MASTER содержат следующую информацию:
Я пытаюсь понять, как я могу пометить действие тегом, а затем связать себя с ответственностью. Это может быть комплексный подход, но мне не хватает опыта здесь. Я, однако, недавно научился реализовывать очень простую настройку аутентификации:
public class FocusAuthenticationAttribute : FilterAttribute, IAuthenticationFilter
{
private readonly ILogService logService = Log4NetService.Instance;
private IEasyLogger Logger { get; }
public FocusAuthenticationAttribute()
{
Logger = logService.GetLogger("Authentication-Log");
}
public void OnAuthentication(AuthenticationContext filterContext)
{
var currentUser = ParseUserNameFromOkta(filterContext.HttpContext.User.Identity.Name);
if (filterContext.HttpContext.Session[Constants.SessionVariableCurrentUser] == null)
{
filterContext.HttpContext.Session[Constants.SessionVariableUserName] = "";
filterContext.HttpContext.Session[Constants.SessionVariableUserJobTitle] = "";
var businessUserDetails = new UsersClient().FindUser(currentUser);
if (businessUserDetails != null)
{
businessUserDetails.UserThumb = GetUserThumbFromActiveDirectory("Domain", businessUserDetails.UserId, "thumbnailPhoto");
var jobTitle = GetUserPropertyFromActiveDirectory("Domain", businessUserDetails.UserId, "title");
if (!string.IsNullOrEmpty(jobTitle))
{
businessUserDetails.JobTitle = jobTitle;
}
var businessUser = new BusinessUser(businessUserDetails);
filterContext.HttpContext.User = businessUser;
filterContext.HttpContext.Session[Constants.SessionVariableCurrentUser] = businessUser;
filterContext.HttpContext.Session[Constants.SessionVariableCurrentUserId] = businessUser.Id;
}
else
{
filterContext.HttpContext.Response.Redirect("~/Meta/AccessDenied");
filterContext.HttpContext.Response.End();
}
}
else
{
if (filterContext.HttpContext.Session[Constants.SessionVariableCurrentUser] is BusinessUser user)
{
filterContext.HttpContext.User = user;
filterContext.HttpContext.Session[Constants.SessionVariableCurrentUserId] = ((BusinessUser)filterContext.HttpContext.User).Id;
}
else
{
filterContext.HttpContext.Response.Redirect("~/Meta/AccessDenied");
filterContext.HttpContext.Response.End();
}
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
var user = filterContext.HttpContext.User;
if (user == null || !user.Identity.IsAuthenticated)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
private (string Domain, string StaffId) ParseUserNameFromOkta(IIdentity identity)
{
return (identity.GetDomain(), identity.GetLogin());
}
private string ParseUserNameFromOkta(string receivedUserName)
{
var regexPattern = @"^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$";
var matches = Regex.Match(receivedUserName, regexPattern);
if (!matches.Success) return receivedUserName;
var domainUser = new MailAddress(receivedUserName);
var staffId = domainUser.User;
var domain = "Domain";
var businessUser = $"{domain}\\{staffId}";
return businessUser;
}
private static string GetUserPropertyFromActiveDirectory(string domain, string userName, string propertyName)
{
var result = GetDirectoryObjectFromActiveDirectoryProperty(domain, userName, propertyName);
return result != null ? Convert.ToString(result) : string.Empty;
}
private static byte[] GetUserThumbFromActiveDirectory(string domain, string userName, string propertyName)
{
}
private static object GetDirectoryObjectFromActiveDirectoryProperty(string domain, string userName, string profileProperty)
{
}
private static SearchResult GetDirectoryRecordFromActiveDirectory(string domain, string userName)
{
}
}
Этот атрибут наследуется всеми моими контроллерами. Сайт находится только в интранете, и у нас есть Okta как SSO.
Как мне перейти к простой в использовании реализации, где роль пользователя рассматривается для каждого действия? Я также понял, что мне нужно создавать роли с повторяющимися именами (например, "Бухгалтер I" и "Бухгалтер II") из-за сочетания обязанностей и сверхурочной работы, это создаст беспорядок на странице администратора для назначения ролей.