MVC3 Windows Authentication переопределить User.Identity
Я строю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; }
}
и переопределение аутентификации Windows для заполнения пользовательского принципала.
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 с помощью C #:
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();
}
}
Теперь, когда я ставлю точку останова, часы показывают следующее для пользователя:
User [CSupport.Model.CPrincipal] IdentityИдентичность доступна; тем не менее, это все еще 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);
}
}
Вот переопределение атрибута Authorize
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 обрабатывает все на индивидуальном уровне.