MVC3 Windows-Authentifizierung Benutzer überschreiben.Identität
Baue ich ein intranet Anwendung mit MVC3 mit einem MSSQL backend. Ich habe Authentifizierung und Rollen (durch eine benutzerdefinierte Rollen-provider) funktionieren. Was ich versuche zu tun, ist jetzt überschreiben Benutzer.Identität zu ermöglichen, für Objekte wie Benutzer.Identität.Vorname. Aber ich kann nicht finden code, die mir zeigen, wie dies in WindowsIdentity
Habe ich versucht, das schreiben eines benutzerdefinierten Anbieters:
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; }
}
und überschreiben die WindowsAuthentication zum Auffüllen der benutzerdefinierten principal.
void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
if (e.Identity != null && e.Identity.IsAuthenticated)
{
CPrincipal cPrincipal = new CPrincipal(e.Identity);
HttpContext.Current.User = cPrincipal;
}
}
Habe ich einen Haltepunkt in die Authentifizierungs-Funktion und der AUFTRAGGEBER wird aufgefüllt, aber wenn ich einen Haltepunkt für den Controller, der User ist nur seine normale RolePrincipal, anstatt meine benutzerdefinierten principal. Was mache ich falsch?
EDIT:
Ich auskommentiert den code oben in die global.asax.
Ich überschrieben haben, die AuthorizeAttribute mit 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;
}
}
Und meinen AUFTRAGGEBER um die folgenden:
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();
}
}
Ich jetzt wenn ich einen breakpoint in die Uhr zeigt die folgenden Benutzer verwenden:
- Benutzer
- [CSupport.Modell.CPrincipal]
- Identität
Identität ist zugänglich, aber es ist immer noch die WindowsIdentity
CPrincipal ist nur zugänglich in der Uhr und nicht direkt zugänglich.
EDIT:
Vielen Dank an alle, die dazu beigetragen haben. Sie haben sich stark erweitert mein Verständnis, wie die verschiedenen Teile funktionieren.
Habe ich beide Möglichkeiten zu arbeiten, so dass ich dachte, ich würde teilen.
Option 1: Überschreiben Sie die Autorisierung-Anforderung in der Globalen.asax
Dies ist die eine ich werde.
Ich nicht verwenden, Application_AuthenticateRequest, weil (nach: HttpContext.Aktuelle.User ist null, obwohl die Windows-Authentifizierung ist auf) der Benutzer wurde nicht aufgefüllt, in ein Windows-Authentifizierung-Prozess und somit gibt es nichts, das ich verwenden kann, um sich die Informationen für den Benutzer.
Application_AuthorizeRequest ist der nächste in der Kette ist und geschieht, nachdem die windows-Identität gebracht wird.
protected void Application_AuthorizeRequest(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated && Roles.Enabled)
{
Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
}
}
Dies ist die überschreibung der AUFTRAGGEBER
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);
}
}
Dies ist, wie Sie den Zugriff auf die aktualisierten Informationen in den neuen AUFTRAGGEBER erstellt wurde.
[Authorize(Roles = "super admin")]
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; //<--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
Option 2: Überschreiben der AuthorizeAttribute
Dies ist die überschriebene AUFTRAGGEBER (Es ist die gleiche wie oben)
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);
}
}
Hier ist das überschreiben von " aktivieren Attribut
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;
}
}
Dies ist, wo ändern Sie die AuthorizeAttribute zur Nutzung und Anwendung der neuen Informationen.
[CAuthorize(Roles = "super admin")] //<--
public ActionResult Dashboard()
{
string firstname = (User as CPrincipal).userInfo.FirstName; //<--
DashboardModel dModel = reportDAL.GetChartData();
return View(dModel);
}
Option 1 behandelt alles Global, option 2 Griffe alles auf einer individuellen Ebene.
Ich bin mit windows-Authentifizierung auf einer intranet-site. Dieser event-handler wird in der globalen.asax
Es gibt keine OnAuthenticate-handler in die Globale.asax. Das ist wahrscheinlich der Grund, warum Sie Probleme haben.
Sie haben zu werfen es zu einem WindowsIdentity, wenn Sie es verwenden. Oder, verwenden Sie die Erweiterung Methode, die ich unten gemacht.
Wenn ich die Besetzung der Identität als ein WindowsIdentity in CPrincipal, es gibt den folgenden Fehler: 'CSupport.Modelle.CPrincipal.Identität' nicht implementiert ' - System.Sicherheit.AUFTRAGGEBER.IPrincipal.Identität", weil es nicht die passenden Rückgabetyps von 'System.Sicherheit.AUFTRAGGEBER.IIdentity " Wenn ich die überschreiben, um WindowsPrincipal, ich bekomme diese Fehlermeldung: 'System.Sicherheit.AUFTRAGGEBER.WindowsPrincipal' enthält keinen Konstruktor, der 0-Argumente
InformationsquelleAutor Toby Jones | 2012-09-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Anstatt es zu tun auf diese Weise, die Sie überschreiben sollten, die Application_AuthenticateRequest-Methode in der global.asax, dann verwenden Sie eine Aktuelle.Benutzer und nicht als HttpContext.Aktuelle.Benutzer (nicht sicher, warum, aber es ist ein Unterschied).
Dann eine einfache Möglichkeit, dies in Ihrer Steuerung ist die Erstellung einer extension-Methode? So etwas wie dieses:
dann kann man nur sagen
User.Identity.IMyIdenty().FirstName
. Wahrscheinlich könnte man dies als eine Eigenschaft als gut.Hier ist der code den ich benutze:
Nun, ignorieren die DependencyResolver Zeug-und custom-auth-ticket-Zeug, das ist ziemlich einfach und funktioniert richtig für mich.
Dann in meiner app, wenn ich brauche info von meine eigene Identität, ich werfe es mit
((IMyIdentity)User.Identity).FirstName
oder was auch immer ich brauche. Es ist kein Hexenwerk, und es funktioniert.protected void Application_AuthenticateRequest(object sender, EventArgs e) { if (HttpContext.Current.User.Identity != null && HttpContext.Current.User.Identity.IsAuthenticated) { HttpContext.Current.User = new CPrincipal(HttpContext.Current.User.Identity); } }
siehe mein edit. Es ist Ihr job zu tun, wird die Authentifizierung in AuthenticateRequest. Der Benutzer ist natürlich Null, weil keine Authentifizierung hat noch aufgetreten.
InformationsquelleAutor Erik Funkenbusch
Wahrscheinlich die
[Authorize]
Attribut überschreiben Ihre änderungen. Also anstatt dies zu tun, in derWindowsAuthentication_OnAuthenticate
Methode in IhrerGlobal.asax
schreiben Sie eine benutzerdefinierteAuthorize
Attribut, etwa so:und verwenden Sie dann Ihr benutzerdefiniertes Attribut anstelle des Standard ein:
In ASP.NET MVC-der standard-Weg zu führen, wird die Autorisierung durch die Autorisierung action-Filter, nicht durch Ereignisse in die Globale.asax.
Trotzdem, es ist schlechte Praxis, um Ereignisse in
Global.asax
zum durchführen von Autorisierung in einem ASP.NET MVC-Anwendung. Sie sollten verwenden Sie benutzerdefinierte Autorisierungs-Filter statt.Er leistet keine Berechtigung in seinen code, er ist nur die Anwendung seiner Gewohnheit AUFTRAGGEBER, die afaik sollte noch getan werden, in global.asax.
Nein, ich glaube nicht, dass die Anwendung der benutzerdefinierten Principal im Global.asax ist eine gute Idee. Dieser code ist völlig unüberprüfbare isoliert und nur schwer angewendet werden bedingt auf bestimmte controller-Aktionen werden nur. Was, wenn Sie wollten, gilt die Genehmigung nur auf bestimmte Bereiche? Global.asax ist nicht die richtige Art und Weise zum durchführen von Autorisierung in einem ASp.NET MVC-Anwendung. Das ist meine Meinung natürlich. Ich habe Respekt vor Ihnen und Sie sind frei zu tun, Berechtigung, wo immer Sie wollen.
Gut, ich habe noch nie gestoßen, eine app, die verwendet verschiedene Arten von Auftraggebern in den verschiedenen teilen der app, aber ich nehme an, wenn das, was Sie brauchen, sicher. Allerdings habe ich das Gefühl, dass die benutzerdefinierten principal gesetzt werden sollten, so früh wie möglich in die event-Kette, um zu verhindern, dass Situationen, in denen ein Ereignis sieht ein AUFTRAGGEBER aber ein anderes Ereignis sieht, eine andere. Es ist relativ einfach zu erstellen einer prüfbaren wrapper für diese, aber das ist der Punkt, dass es eine Schnittstelle sowieso. Aber ja, ich denke, wir haben unterschiedliche Meinungen zu diesem Thema.
InformationsquelleAutor Darin Dimitrov