2013-08-14 15 views
5

Un collega mi ha chiesto oggi come configurare IIS 7.5 per utilizzare l'autenticazione integrata di Windows con rappresentazione per un sito Web intranet semplice con contenuto statico limitato a un gruppo specifico in Active Directory (ad es. "Amministratori").Configurare IIS Autenticazione Windows per restituire HTTP 403 anziché HTTP 401 per autorizzazione negata con un utente autenticato

Si scopre che IIS invia una risposta HTTP 401 quando l'utente autenticato non dispone dell'autorizzazione alla risorsa richiesta. L'autorizzazione negata potrebbe essere il risultato di un file ACL NTFS o di un ACL system.webServer/security/authorization definito nella configurazione di IIS.

Tutti i principali browser sembrano interpretare questo 401 per indicare che l'utente finale ha fornito credenziali di nome utente/password di Windows non valide, e quindi richiede all'utente di inserire il proprio nome utente/password. IE sembra richiedere fino a 3 volte prima di mostrare il corpo/contenuto della risposta 401. Chrome e Safari sembrano richiedere ripetutamente all'utente.

Questo può essere fonte di confusione per gli utenti finali, che continuano a inserire ripetutamente un nome utente/password Windows valido, solo per essere nuovamente richiesti.

Il modo migliore sarebbe per IIS per restituire un HTTP 403 invece di un HTTP 401:

403 Forbidden

Il server capito la richiesta, ma si rifiuta di compierla. La richiesta di autorizzazione non è e la richiesta NON DOVREBBE essere ripetuta.

Fonte: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4

Come si configura IIS l'autenticazione integrata di Windows per inviare HTTP 401 per errori di accesso e HTTP 403 per permesso negato?

risposta

6

Che cosa non ha funzionato

ho provato quasi ogni permutazione configurazione di IIS senza fortuna. Ho sbagliato con le impostazioni del provider di autenticazione di Windows, come NTLM, Negoziare e Negoziare: Kerberos. Nessuno di loro sembrava fare il trucco. Questa non è una sorpresa perché i browser decidono di provare nuovamente l'autenticazione, anche se probabilmente non dovrebbero farlo.

401 Unauthorized

La richiesta richiede l'autenticazione dell'utente. La risposta DEVE includere un campo di intestazione WWW-Authenticate (sezione 14.47) contenente una richiesta di sfida per la risorsa richiesta. Il client PU MAY ripetere la richiesta con un campo di intestazione Autorizzazione appropriato (sezione 14.8). Se la richiesta includeva già le credenziali di autorizzazione, , la risposta 401 indica che l'autorizzazione è stata rifiutata per tali credenziali.

Fonte: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2

Che cosa ha fatto il lavoro

ho deciso di sfruttare un po 'verso il basso e sporco ASP.NET per risolvere questo problema.Sotto implementa la riscrittura delle risposte con l'aiuto di un paio di file di testo sul server e la compilazione dinamica ASP.NET. (Non ho mai utilizzato la compilazione dinamica in precedenza, ma la compilazione sembrava eccessiva per un sito statico.)

Il file Global.asax sotto aggancia l'evento EndRequest, riscrivendo una risposta HTTP 401 in un 403 HTTP se l'utente ha eseguito correttamente l'operazione. autenticato come utente di Windows, ma, per qualche altro motivo, la richiesta viene rifiutata (presumo che il motivo debba essere un errore di autorizzazione).

Il file web.config contiene voci per instradare tutte le richieste attraverso la pipeline ASP.NET e negare l'accesso a qualsiasi utente autenticato che non è un membro nel gruppo di Windows "Vendite".

Questa soluzione presuppone che si disponga di un'app in esecuzione in modalità pipeline integrata IIS (vale a dire non in modalità classica), attivata l'autenticazione di Windows e disabilitata tutti gli altri schemi di autenticazione.

/Global.asax:

<Script language="C#" runat="server"> 
    void Application_EndRequest() { 
      // rewrite HTTP 401s to HTTP 403s if the user is authenticated using 
      // integrated Windows auth with impersonation, but, 
      // the user lacks permissions to the requested URL 
      if (Context.User != null && 
        Context.User.Identity != null && 
         Context.User.Identity.IsAuthenticated && 
          Context.User is System.Security.Principal.WindowsPrincipal && 
           Context.Response.StatusCode == 401) 
      { 
       Context.Response.Clear(); 
       Context.Response.StatusCode = 403; 
      } 
     } 
</script> 

/web.config:

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <system.webServer> 
     <security> 
      <authorization> 
       <remove users="*" roles="" verbs="" /> 
       <add accessType="Allow" roles="Sales" /> 
      </authorization> 
     </security> 
     <modules runAllManagedModulesForAllRequests="true" /> 
    </system.webServer> 
</configuration> 

Per riferimento futuro, ho creato un Gist @ https://gist.github.com/steve-jansen/6234700

+0

Questo appare come una risposta a un problema Sto avendo. Qualcuno può spiegare dove sono questi file e/o come controllo la modalità pipeline. Inoltre, se voglio consentire questo a tutti anziché solo alle vendite, come faccio a farlo, o posso semplicemente lasciare quella parte ... – Rothrock

+0

@Rothrock Ho appena avuto questo con IIS 8.5. Ho sprecato 1,5 ore per capire perché IIS stava rifiutando il mio ticket Kerberos cross-forest con 401 invece mi dava 403. Questo è un bug, c'è un modo migliore per risolvere questo? 401 è chiaramente il codice di stato sbagliato. Sembra un tipico scherzo di MS per me. –

Problemi correlati