2012-01-26 7 views
14

dopo molte ricerche su google e la lettura di diverse soluzioni su come gestire l'autenticazione in modalità mista nelle app ASP.NET, non ho ancora una soluzione adeguata per il mio problema.Estensione dell'autenticazione di Windows nell'applicazione ASP.NET MVC 3

Devo implementare un'applicazione intranet per un gruppo di diversi gruppi di utenti. Fino ad ora ho usato l'autenticazione di Windows, che era molto semplice da implementare. I miei problemi sorgono quando si tratta di autorizzare gruppi di utenti per funzionalità di applicazioni speciali.

L'utilizzo di [Authorize(Users = "DOMAIN\\USER")] funziona in modo ottimale ma, a causa di ciò, non ho accesso al gestore di directory attivo, è impossibile configurare il rolemanagement nel modo in cui ne ho bisogno per la mia applicazione.

Quello che mi piacerebbe fare è definire ruoli personalizzati e appartenenze in aggiunta a quelli che sono definiti all'interno della directory attiva (tale estensione è possibile? Ad esempio implementando un proprio memberhipprovider?).

Quale pensi sia la soluzione migliore per il mio problema. Devo davvero implementare una complessa autenticazione in modalità mista con l'autenticazione dei moduli oltre all'autenticazione di Windows?

tecnologie utilizzate:

  • MS SQL Server 2008
  • MS VS 2010
  • ASP.NET MVC 3 - Razor View Engine
  • Telerik estensioni per ASP.NET MVC
  • IIS 7 su Windows Server 2008

E DIT (soluzione finale grazie all'aiuto di dougajmcdonald):

Dopo avermi utilizzare un'implementazione personalizzata IPrincipal ho trovato alcune soluzioni here e here. Mettendo tutto insieme sono giunto alla seguente soluzione:

1.Creare un'implementazione principal personalizzato:

public class MyPrincipal: WindowsPrincipal 
{ 
    List<string> _roles; 

    public MyPrincipal(WindowsIdentity identity) : base(identity) { 
     // fill roles with a sample string just to test if it works 
     _roles = new List<string>{"someTestRole"}; 
     // TODO: Get roles for the identity out of a custom DB table 
    } 

    public override bool IsInRole(string role) 
    { 
     if (base.IsInRole(role) || _roles.Contains(role)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

2.Integrate mia implementazione principale personalizzata nell'applicazione attraverso l'estensione del file "Global.asax.cs" :

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     if (Request.IsAuthenticated) 
     { 
      WindowsIdentity wi = (WindowsIdentity)HttpContext.Current.User.Identity; 
      MyPrincipal mp = new MyPrincipal(wi); 
      HttpContext.Current.User = mp; 
     } 
    } 

3.Use i miei ruoli personalizzati per l'autorizzazione nella mia applicazione

public class HomeController : Controller 
{ 
    [Authorize(Roles= "someTestRole")] 
    public ActionResult Index() 
    { 
     ViewBag.Message = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 
} 

Funziona !!! si!

risposta

8

non sono sicuro se questo vale ancora in MVC, ma in Webforms un modo per fare questo potrebbe essere il seguente:

  1. Creare una nuova implementazione IPrincipal forse estendere WindowsPrincipal
  2. In questa classe, assegnagli una serie di ruoli (i tuoi ruoli personalizzati)
  3. Compila questi ruoli, forse recuperandoli dal DB.
  4. Ignora IsInRole per restituire true se il ruolo fornito è EITHER true dalla chiamata di base (WindowsAuthentication/Role) OPPURE dalla propria raccolta di ruoli personalizzata.

In questo modo è ancora possibile collegare in Principal.IsInRole ("MyRole") e anche l'annotazione principale [PrincipalPermission()].

Spero che aiuti.

EDIT in risposta alla q di:

di integrare il principale nel autorizzazioni necessarie per scrivere il proprio metodo per OnAuthenticate nel global.asax per il tipo di autenticazione, in modo direi per te, qualcosa di simile:

void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e) 
{ 
    // ensure we have a name and made it through authentication 
    if (e.Identity != null && e.Identity.IsAuthenticated) 
    { 
     //create your principal, pass in the identity so you know what permissions are tied to 
     MyCustomePrincipal opPrincipal = new MyCustomePrincipal(e.Identity);    
     //assign your principal to the HttpContext.Current.User, or perhaps Thread.Current 
     HttpContext.Current.User = opPrincipal;  
    } 
} 

credo Autorizza entrato in una data successiva al PrincipalPermission, ma io non sono troppo sicuro quanto a quando/perché delle differenze temo :(- dispiace

!
+0

lo darò una prova, grazie per la risposta veloce :) –

+0

oh grazie mille !!! La tua risposta è stata molto utile! :-) –

+0

Nessun problema, lieto che abbia aiutato. Ho dovuto fare qualcosa di molto simile molto recentemente! Nella mia situazione non volevo usare i ruoli di Windows Active Directory (dato che i nostri amministratori non vogliono gestire le cose in questo modo) ma volevo assicurarci che potessimo usarli se decidessero di farlo, quindi la decisione di collegarsi all'IPrincipal lato delle cose piuttosto che creare un account utente come una classe interna alla nostra app e attaccare i ruoli contro di essa. – dougajmcdonald