5

Ich habe eine Menge Fragen und Antworten zu diesem Thema gelesen, aber keiner von ihnen hat mir geholfen, dieses Problem zu lösen.Benutzerdefinierte IPrincipal nicht zugänglich in MVC5

Das Problem, das ich habe, ist, dass die HttpContext.Current.User oder nur User Eigenschaft vom Typ RolePrincipal anstelle von meinem benutzerdefinierten Prinzipal ist.

Dies ist eine MVC 5-Webanwendung mit Windows-Authentifizierung (Intranet-Anwendung). Mein benutzerdefinierter Prinzipal ist eine Unterklasse von WindowsPrincipal, und ich habe meine eigene RoleProvider zur Verwendung in Autorize-Attribut-Tags implementiert.

Wenn ich versuche, den Prinzipal zu verwenden, indem ich es auf meine benutzerdefinierte Prinzipal aus IPrincipal auf dem aktuellen HttpContext werfen, erhalte ich eine Fehlermeldung, dass es vom Typ RolePrincipal ist, die natürlich nicht zu meinem benutzerdefinierten Prinzipal gegossen werden kann. Ich gründe mein benutzerdefiniertes Haupt im Application_PostAuthenticationRequest Ereignisse:

protected void Application_PostAuthenticationRequest(object sender, EventArgs e) 
{ 
    if (User == null) 
     return; 

    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
    } 
} 

Als ich in diesem Verfahren einen Haltepunkt setzte es scheint nie aufgerufen, was erklären könnte, warum es nicht zu meinem benutzerdefiniertes Haupt gesetzt zu werden.

Ich habe die folgende QAs prüft, aber sie haben es nicht gelungen, das Problem zu beheben:

Was mache ich falsch, um das Prinzipal nicht zu haben? Lassen Sie mich wissen, ob mehr Code veröffentlicht werden muss.

BEARBEITEN Sie: Das Festlegen des HttpContext.Current.User zu meinem benutzerdefinierten Prinzipal in dem WindowsAuthentication.OnAuthenticate-Ereignis löst dieses Problem nicht. Das exakt gleiche Verhalten zeigt sich mit dieser Methode.

Antwort

1

Nach kontinuierlich sucht dieses Problem fand ich endlich die Antwort durch eine andere Frage SO meine Frage Art eines Duplikats machen: MVC3 Windows Authentication override User.Identity

Im Folgenden finden Sie die Antwort veröffentlicht von @Toby Jones (als bearbeiten seine ursprüngliche Frage), die zu meiner Lösung meines Problems führen, aber seine Antwort ist eigentlich die Zusammenfassung von zwei Antworten von @Erik Funkenbusch & @Darin Dimitrov. Die Antwort wird bearbeitet, um einige Grammatik & zu beheben, um einige überflüssige Informationen zu entfernen.

Option 1: Überschreiben Sie die Autorisierungsanforderung in Global.asax

Das Application_AuthenticateRequest Ereignis sollte, weil nicht verwendet werden (HttpContext.Current.User null ist, obwohl die Windows-Authentifizierung aktiviert ist) hat der Benutzer nicht in dem Windows-Authentifizierungsprozess bevölkert, und somit gibt es nichts, dass ich den Benutzer erhalten verwenden kann Information.

Application_AuthorizeRequest ist der nächste in der Kette und passiert nach der Windows in

protected void Application_AuthorizeRequest(object sender, EventArgs e) 
{ 
    if (User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     Context.User = new CustomPrincipal((WindowsIdentity)User.Identity); 
    } 
} 

Option 2 gebracht wird. Überschreiben Sie die AuthorizeAttribute

Hier wird die Überschreibung der Autorisieren

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; 
    } 
} 

Ersetzen Sie dann alle AuthorizeAttributes durch die benutzerdefinierte Version.

Option 1 behandelt alles global, während Option 2 alles auf einer individuelleren Ebene mit Filtern behandelt.

Persönlich wählte ich die global.asax-Methode, so dass ich meine benutzerdefinierte Principal weltweit verfügbar haben. Hier ist der eigentliche Code, der mein Problem gelöst hat:

protected void Application_AuthorizeRequest(object source, EventArgs e) 
{ 
    if(User.Identity.IsAuthenticated && Roles.Enabled) 
    { 
     using (EntityContext db = new EntityContext()) 
     { 
      var user = db.Users.Include("Roles").SingleOrDefault(u => u.ADName.Equals(User.Identity.Name)); 
      if (user == null) 
       return; 

     PcsPrincipal principal = new PcsPrincipal((WindowsIdentity)User.Identity, user); 
      Context.User = principal; 
     } 
    }    
} 
1

Sie sollten den benutzerdefinierten Prinzipal im WindowsAuthentication_OnAuthenticate-Ereignis festlegen, das auftritt, wenn die Anwendung die aktuelle Anforderung authentifiziert.

protected void WindowsAuthentication_OnAuthenticate(object source, WindowsAuthenticationEventArgs e) 
{ 
    using(EntityContext db = new EntityContext()) 
    { 
     var user = db.Users.SingleOrDefault(u => u.ADName.Equals(e.Identity.Name)); 
     HttpContext.Current.User = new PcsPrincipal(e.Identity, user); 
    } 
} 
+0

Das gleiche Verhalten wird mit dem Ereignis "WindowsAuthentication.OnAuthenticate" angezeigt. – JNYRanger