2013-05-01 11 views
7

Abbiamo un'applicazione Web API che fornisce una serie di metodi Web che i client possono chiamare e consumare. Sarà ospitato in IIS e avrà l'impostazione SSL.Come utilizzare l'autenticazione di Active Directory con l'API Web ASP.NET?

Le credenziali dell'utente sono memorizzate in Active Directory ma i client non sono solo all'interno del nostro dominio, ma possono essere ovunque nel mondo, quindi non è possibile utilizzare l'autenticazione integrata di Windows.

Qual è il modo migliore per autenticare gli utenti nel nostro scenario come spiegato sopra?

Dovrei chiedere agli utenti di passare nome utente/password nell'intestazione con ogni richiesta effettuata? Quindi convalido le credenziali dell'utente rispetto alla nostra Active Directory a livello di codice (abbiamo già un componente che lo fa), ad es. creando un ActionFilter personalizzato che viene eseguito prima dell'esecuzione di ogni azione?

Un altro approccio potrebbe essere la creazione di un HttpModule eseguito prima di ogni richiesta e che esegue l'autenticazione e, se non valida, interrompe la richiesta.

mio attributo personalizzato sarebbe simile a questa:

public class ActiveDirectoryAuthAttribute : ActionFilterAttribute 
    { 
     // todo: load from config which can change depending on deployment environment 
     private static readonly bool ShouldRequireHttps = false; 

     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      IPrincipal principal = this.Authentiate(actionContext); 

      if (principal == null) 
      { 
       actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized); 
      } 
      else 
      { 
       this.SetPrincipal(principal); 
      } 
     } 

     private IPrincipal Authentiate(HttpActionContext actionContext) 
     { 
      if (IsUriSchemaValid(actionContext.Request.RequestUri)) 
      { 
       // is the client certificate known and still valid? 
       // is IP valid? 
       // find user credentials and validate against AD 
       // create the Principle object and return it 
      } 

      return null; 
     } 

     private void SetPrincipal(IPrincipal principal) 
     { 
      Thread.CurrentPrincipal = principal; 

      if (HttpContext.Current != null) 
      { 
       HttpContext.Current.User = principal; 
      } 
     } 

     private static bool IsUriSchemaValid(Uri uri) 
     { 
      bool result = true; 

      if (ShouldRequireHttps) 
      { 
       if (!string.Equals(uri.Scheme, "https", StringComparison.InvariantCultureIgnoreCase)) 
       { 
        result = false; 
       } 
      } 

      return result; 
     } 
    } 

Poi dentro la mia azione di controllo che può ottenere l'accesso all'oggetto Principio:

IPrincipal principle = this.User; 

Qual è il modo migliore per l'autenticazione/autorizzazione degli utenti nel nostro scenario come spiegato sopra?

In Sopra, come creare un oggetto da IPrinciple? Esiste una classe .NET esistente o dovrei creare la mia classe personalizzata?

risposta

2

Ultimamente ho lavorato un po 'con AD e non riesco a pensare ad un altro modo di gestirlo per essere onesti.

Potrebbe essere più sensato utilizzare un approccio di tipo OAuth. Fornire una route del tipo di token che inizialmente utilizzerà nome utente e password e restituire un token autoprocesso e crittografato al destinatario. Una volta effettuata la prima chiamata iniziale, inviare il token al call e quindi utilizzare quel token nell'intestazione Autorizzazione per ogni chiamata successiva all'API.

I token sarebbero validi per una chiamata o uno spazio molto breve di tempo. Ogni volta che si considera il token da utilizzare, emetterne un altro.

Si potrebbe anche guardare utilizzando un'implementazione OAuth personalizzata per questo e invece di utilizzare un database per il processo di autenticazione utilizzare il proprio archivio identità AD e utilizzare i token OAuth Bearer. Dal momento che stai usando SSL questo è in realtà un buon adattamento per il tuo scenario.

Problemi correlati