Sto creando un'applicazione intranet utilizzando MVC3 con un backend MSSQL. Ho un'autenticazione e ruoli (attraverso un fornitore di ruoli personalizzati) che funzionano correttamente. Quello che sto cercando di fare ora è sovrascrivere User.Identity per consentire elementi come User.Identity.FirstName. Ma non riesco a trovare alcun codice che mi mostrerà come fare questo in WindowsIdentityMVC3 Autenticazione di Windows ignora User.Identity
Ho provato a scrivere un provider personalizzato:
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; }
}
e ignorando l'WindowsAuthentication per popolare il preside personalizzata.
void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity != null && e.Identity.IsAuthenticated)
{
CPrincipal cPrincipal = new CPrincipal(e.Identity);
HttpContext.Current.User = cPrincipal;
}
}
Ho un punto di interruzione nella funzione di autenticazione e il principale viene popolato; tuttavia, quando inserisco un punto di interruzione nei controller, l'utente è solo il suo normale RolePrincipal, anziché il mio principal personalizzato. Che cosa sto facendo di sbagliato?
EDIT:
ho commentato il codice sopra nella global.asax. ho ignorato l'AuthorizeAttribute utilizzando 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;
}
}
e regolato il mio principale al seguente:
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();
}
}
Ora io quando ho messo un punto di interruzione, l'orologio mostra quanto segue utente:
- utente
- [CSupport.Model.CPrincipal]
- Identità
identità è accessibile; tuttavia, è ancora WindowsIdentity CPrincipal è accessibile solo nell'orologio e non è accessibile direttamente.
MODIFICA: Grazie a tutti coloro che hanno contribuito a questo. Hai notevolmente ampliato la mia comprensione di come funzionano le varie parti.
Ho avuto entrambi i modi di lavorare, quindi ho pensato di condividere.
Opzione 1: Eseguire l'override del Request Autorizza in Global.asax
Questo è quello che sto con.
Non ho utilizzato Application_AuthenticateRequest perché (in base a questo: HttpContext.Current.User is null even though Windows Authentication is on) l'utente non è stato popolato in un processo di autenticazione di Windows e quindi non c'è nulla che possa essere utilizzato per ottenere le informazioni dell'utente.
Application_AuthorizeRequest è il prossimo della catena e si verifica dopo l'introduzione dell'identità di Windows.
protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated && Roles.Enabled)
{
Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
}
}
Questa è l'override del Principal
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);
}
}
In questo modo si accede alla informazioni aggiornate nel nuovo Principal che è stato creato.
[Authorize(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
Opzione 2: Eseguire l'override del AuthorizeAttribute
Questa è la principale sovrascritto (E 'lo stesso come sopra)
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);
}
}
Ecco l'override del Autorizza Attributo
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;
}
}
Qui è dove si modifica quale AuthorizeAttribute utilizzare e si utilizzano le nuove informazioni zione.
[CAuthorize(Roles = "super admin")] // <--
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; // <--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
L'opzione 1 gestisce tutto a livello globale, l'opzione 2 gestisce tutto a livello individuale.
Attendi ... Che cos'è questo gestore eventi? Non stai provando a usare il controllo di accesso di ASP.NET sei? Dove si trova questo evento e in quale evento si sta vincolando? –
Sto usando l'autenticazione di Windows su un sito intranet. Questo gestore di eventi è globale.asax –
Non esiste un gestore OnAuthenticate in global.asax. Questo è probabilmente il motivo per cui hai problemi. –