Я создаю приложение intranet, используя MVC3 с бэкэнд MSSQL. У меня есть проверка подлинности и роли (через поставщика настраиваемых ролей), работающих должным образом. То, что я пытаюсь сделать сейчас, - это переопределить User.Identity, чтобы разрешить такие элементы, как User.Identity.FirstName. Но я не могу найти код, который покажет мне, как это сделать в WindowsIdentity
Я пробовал написать пользовательский поставщик:
public class CPrincipal : WindowsPrincipal
{
UserDAL userDAL = new UserDAL();
public CPrincipal(WindowsIdentity identity)
: base(identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.identity = identity;
}
public UserInfo userInfo { get; private set; }
public WindowsIdentity identity { get; private set; }
}
и переопределение WindowsAuthentication для заполнения пользовательского принципала.
void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity != null && e.Identity.IsAuthenticated)
{
CPrincipal cPrincipal = new CPrincipal(e.Identity);
HttpContext.Current.User = cPrincipal;
}
}
У меня есть точка останова в функции аутентификации и заполняется руководитель; однако, когда я устанавливаю точку останова в контроллерах, Пользователь - это просто нормальный RolePrincipal, а не мой пользовательский принцип. Что я делаю неправильно?
EDIT:
Я прокомментировал код выше в global.asax. Я переопределил AuthorizeAttribute с помощью С#:
public class CAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
IIdentity user = httpContext.User.Identity;
CPrincipal cPrincipal = new CPrincipal(user);
httpContext.User = cPrincipal;
return true;
}
}
И скорректировал мой принцип следующим образом:
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
throw new NotImplementedException();
}
}
Теперь, когда я ставлю точку останова, часы показывают пользователю следующее:
- Пользователь
- [CSupport.Model.CPrincipal]
- Идентичность
Идентификация доступна; однако он все еще является WindowsIdentity CPrincipal доступен только в часах и недоступен напрямую.
EDIT: Спасибо всем, кто внес свой вклад в это. Вы значительно расширили мое понимание того, как работают различные части.
У меня есть оба способа работы, поэтому я думал, что поделюсь.
Вариант 1: переопределить запрос авторизации в Global.asax
Это тот, с которым я иду.
Я не использовал Application_AuthenticateRequest, потому что (в соответствии с этим: HttpContext.Current.User имеет значение null, даже если аутентификация Windows включена), пользователь не был заполнен в Процесс проверки подлинности Windows и, следовательно, я ничего не могу использовать, чтобы получить информацию о пользователе.
Application_AuthorizeRequest является следующим в цепочке и происходит после ввода идентификатора Windows.
protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated && Roles.Enabled)
{
Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
}
}
Это переопределение Принципала
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return userDAL.IsUserInRole(userInfo.UserName, role);
}
}
Вот как вы получаете доступ к обновленной информации в новом Создателе, который был создан.
[Authorize(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
Вариант 2: переопределить атрибут AuthorizeAttribute
Это переопределенный Принципал (это то же самое, что и выше)
public class CPrincipal : IPrincipal
{
private UserDAL userDAL = new UserDAL();
public CPrincipal(IIdentity identity)
{
userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
this.Identity = identity;
}
public UserInfo userInfo { get; private set; }
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return userDAL.IsUserInRole(userInfo.UserName, role);
}
}
Вот переопределение атрибута авторизации
public class CAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
IIdentity user = httpContext.User.Identity;
CPrincipal cPrincipal = new CPrincipal(user);
httpContext.User = cPrincipal;
return true;
}
}
Здесь вы меняете атрибут AuthorizeAttribute для использования и использования новой информации.
[CAuthorize(Roles = "super admin")] // <--
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
Вариант 1 обрабатывает все в глобальном масштабе, вариант 2 обрабатывает все на индивидуальном уровне.