5

Ho letto un sacco di domande e risposte su questo argomento, ma nessuno di loro mi ha aiutato a risolvere questo problema.IPrincipal personalizzato non accessibile in MVC5

Il problema che sto avendo è che la proprietà HttpContext.Current.User o solo User è di tipo RolePrincipal invece del mio principal personalizzato.

Questa è un'app Web MVC 5 che utilizza l'autenticazione di Windows (solo per l'intranet). Il mio principal personalizzato è una sottoclasse di WindowsPrincipal e ho implementato il mio RoleProvider per l'utilizzo nei tag di attributo Authorize.

Quando si tenta di utilizzare il principal trasferendolo al mio principal personalizzato da IPrincipal sul HttpContext corrente, viene visualizzato un errore che indica che è di tipo RolePrincipal, che ovviamente non può essere convertito nel mio principal personalizzato. Sto impostando il principale personalizzato in caso Application_PostAuthenticationRequest:

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

Quando ho messo un punto di interruzione nel metodo che sembra mai ottenere chiamato, che può spiegare perché non è sempre impostato la mia principale personalizzato.

ho rivisto il seguente Qas, ma non sono riuscito a risolvere il problema:

Che cosa sto facendo in modo errato per non avere il Preside impostato? Fammi sapere se è necessario pubblicare più codice.

MODIFICA: L'impostazione di HttpContext.Current.User sul mio principal personalizzato nell'evento WindowsAuthentication.OnAuthenticate non risolve questo problema. Lo stesso identico comportamento è esibito usando quel metodo.

risposta

1

Dopo la ricerca continuamente questo problema ho finalmente trovato la risposta per mezzo di un'altra domanda SO fare la mia domanda una sorta di duplicato: MVC3 Windows Authentication override User.Identity

Di seguito è la risposta inviato da @Toby Jones (come una modifica alla la sua domanda originale) che ha portato alla risoluzione del mio problema, ma la sua risposta è in realtà l'aggregazione di due risposte pubblicate da @Erik Funkenbusch & @Darin Dimitrov. La risposta è stata modificata per correggere alcune grammatiche dello & per rimuovere alcune informazioni superflue.

Opzione 1: Sovrascrivi la richiesta di autorizzazione in Globale.ASax

L'evento Application_AuthenticateRequest non deve essere utilizzato a causa (HttpContext.Current.User è nullo anche se l'autenticazione di Windows è attivato) l'utente non è stato popolato nel processo di autenticazione di Windows, e, quindi, non c'è nulla che posso usare per ottenere l'utente informazione.

Application_AuthorizeRequest è il successivo nella catena e avviene dopo la WindowsIdentity viene portato in

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

Opzione 2:. Override l'AuthorizeAttribute

Qui è la sostituzione del Autorizza Abilità

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

Quindi sostituire tutti AuthorizeAttributes alla versione personalizzata.

L'opzione 1 gestisce tutto a livello globale, mentre l'opzione 2 gestisce tutto a un livello più individuale utilizzando i filtri.

Personalmente, ho scelto di utilizzare il metodo global.asax così ho a disposizione il mio principal personalizzato a livello globale. Ecco il codice effettivo che ha risolto il mio problema:

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

È necessario impostare l'entità personalizzata nell'evento WindowsAuthentication_OnAuthenticate che si verifica quando l'applicazione autentica la richiesta corrente.

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

Lo stesso comportamento è mostrato utilizzando l'evento 'WindowsAuthentication.OnAuthenticate'. – JNYRanger