Я новичок в MVC. Я искал и не нашел решения, которое соответствует моим требованиям.
Я разрабатываю веб-портал для внутреннего использования нашей командой, который использует аутентификацию Windows AD для входа в систему. Однако для доступа на основе ролей я создал локальную базу данных, которая может возвращать сведения о роли для пользователя. Я создал собственный фильтр авторизации, который позволяет мне обрабатывать авторизацию на основе роли пользователя. Этот фильтр запрашивает данные из БД, однако проблема с этим подходом заключается в том, что он будет пытаться получить данные из БД для каждого запроса к контроллеру, что делает его дорогостоящим.
Как я могу сохранить данные пользователя, полученные из БД, в токене, чтобы мне не приходилось запрашивать БД для каждого запроса и использовать значения токена внутри фильтра авторизации. Кроме того, я могу использовать значения, полученные для пользователя из базы данных, в любом другом месте приложения. (Есть некоторые другие данные для пользователя, которые у нас есть в базе данных).
Если кто-то может предложить лучший способ добиться этого, пожалуйста, помогите.
Вот код, который я сейчас использую внутри фильтра авторизации:
public class AuthorizeRole : AuthorizeAttribute
{
private bool _authenticated;
private bool _authorized;
public string InRoles { get; set; }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
if (_authenticated && !_authorized)
{
filterContext.Result = new RedirectResult("/account/error");
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
_authenticated = base.AuthorizeCore(httpContext);
if (_authenticated)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
_authorized = false;
return _authorized;
}
}
Пожалуйста, предложите, в каком разделе использовать код, который вы будете предлагать (например, внутри контроллера, внутри фильтра или где-то еще).
Я нашел это решение по адресу: этот сайт, но там оно используется для групп AD.
Это не имеет ничего общего с Azure AD. Это локальное AD. Что касается сохранения сведений о ролях в TempData, не могли бы вы рассказать мне, как это сделать (извините, я новичок в этом) с некоторым примером кода и где использовать этот код.
Ах, извините... В данный момент я занят работой над Azure AD, поэтому, когда вы сказали Active Directory, я неправильно понял. Мои извинения. Таким образом, в вашем ActionResult вы можете установить TempData следующим образом (просто пример): TempData["RoleName"] = "User"; Затем вы можете использовать его следующим образом: string userRoleName = TempData["RoleName"].ToString(); - Опять же, не уверен, что это то, что вы ищете, но таким образом вы можете передавать данные из одного контроллер к другому без включения его в ваш URL-адрес.
Но нам нужно проверить роль, прежде чем мы достигнем результата действия, верно! В коде, который я разместил, я проверяю AuthorizeAttribute, находится ли пользователь в роли или нет, и это происходит даже до достижения результата действия для любого контроллера. Теперь вопрос в том, где я должен установить TempData.
@SavindraSingh, вы используете .NET Core?
Нет. Я использую только Asp.net MVC.
@SavindraSingh вы используете SignInManager или что-то подобное для управления входом пользователя в систему?
Я не знаю, что такое SignInManager. Я использую аутентификацию Windows для аутентификации пользователя, но мне нужно проверить таблицу базы данных для проверки доступа на основе ролей.





Во-первых, вы можете рассмотреть возможность использования групп безопасности AD для управления доступом. Таким образом, OPS сможет продолжать поддерживать доступ на знакомой, проверенной временем платформе, и вам не придется писать собственный интерфейс определения безопасности.
Что касается сохранения безопасности MVC Все, что вам нужно сделать, это добавить ручной вход в систему для выполнения вышеуказанной логики, а затем вы используете встроенный поставщик членства (для любой версии MVC, которую вы используете) для входа пользователя в систему. MVC будет поддерживать состояние входа в систему. и токенизации для вас, и вы можете указать такие вещи, как тайм-аут в web.config (или settings.json в Core).
Извините, у меня нет примера кода для иллюстрации.
Ранее у меня были планы использовать группы AD. Однако у нашей компании уже есть база данных, которая использовалась для некоторых других приложений, и в соответствии с требованиями я должен использовать ее. Можем ли мы использовать детали роли из базы данных, если да, то я не знаю, как это сделать.
Я проверил файл cookie в переопределяющей версии метода AuthorizeCore, теперь он работает:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = httpContext.Request.Cookies[cookieName];
_authenticated = base.AuthorizeCore(httpContext);
string authToken = httpContext.Request.Headers["Auth-Token"];
if (_authenticated)
{
if (authCookie == null)
{
if (string.IsNullOrEmpty(InRoles))
{
_authorized = true;
return _authorized;
}
if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
{
string NTID = httpContext.User.Identity.Name.Split('\\')[1];
var roles = InRoles.Split(',');
using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
{
try
{
ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
var user = userResults.FirstOrDefault(all => all.NTID == NTID);
if (user == null)
{
_authorized = false;
return _authorized;
}
else
{
if (roles.Contains(user.Role))
{
_authorized = true;
return _authorized;
}
}
}
catch (Exception)
{
_authorized = false;
return _authorized;
}
}
}
else
{
_authorized = false;
return _authorized;
}
}
}
_authorized = false;
return _authorized;
}
Я относительно новичок в Azure AD, но как насчет сохранения сведений о роли в TempData, а затем передачи их на каждую страницу, где они могут вам понадобиться? Возможно, слишком просто, или мне не хватает того, что вы хотите сделать?