2013-08-30 13 views
16

Sto sviluppando un'applicazione mobile HTML5, che comunica con WebServices. I servizi Web utilizzano il protocollo di autenticazione NTLM. Sto avendo difficoltà a gestire l'handshake tramite JavaScript. NTLM invia lo 401 unauthorized come risposta al mio POST, a cui non ho trovato alcun modo di rispondere.Javascript/Ajax NTLM Authentication

L'autenticazione NTLM è possibile con JavaScript? Dovrei creare un servizio web proxy con ad es. autenticazione di base intermedia?

mia chiamata jQuery è qualcosa di simile ...

$.ajax({ 
        type: "POST", 
        url: URL, 
        contentType: "text/xml", 
        dataType: "xml", 
        data: soapRequest, 
        username: 'username', 
        password: 'password', 
        xhrFields: { 
         withCredentials: true 
        }, 
        success: processSuccess, 
        error: processError 
}); 

risposta

4

Per quanto ho visto, nessuno ha implementato Windows integrata/NTLM autenticazione con AJAX, anche se dovrebbe essere possibile (sto pensando di fare per un progetto in corso di combinare l'autenticazione modulo con il WindowsTokenRoleProvider)

il flusso di lavoro di base dovrebbe ripartizione come questo (sulla base di articoli here e here):

  1. fare una richiesta GET con un tipo-1 messaggio NTLM codifica Base64 nel "Autorizzazione" intestazione
  2. prendere il tipo-2 messaggio NTLM con codifica Base64 fuori l'intestazione "WWW-Authenticate" nella risposta 401.
  3. eseguire l'operazione NTLM nel noonce ricevuto nel passaggio precedente (purtroppo non ho ancora un esempio di codice)
  4. eseguire una GET finale con un tipo-3 messaggio NTLM base64 codifica nell'intestazione "Authorization" . Questo dovrebbe restituire un 200.

L'autenticazione NTLM su HTTP è più un'implementazione CHAP che utilizza HTTP di quanto non sia una richiesta HTTP autorizzata.

Ti aggiornerò se effettivamente riuscirò a implementarlo. Mi spiace di non poter essere di maggior aiuto.

+2

grande sintesi, gradirebbe implementazione ... –

2

Il problema è che non puoi ottenere il dominio/utente attualmente connesso tramite javascript (o se non riesci a trovare una soluzione).

Se si conosce già il dominio, username e password si potrebbe usare qualcosa come https://github.com/erlandranvinge/ntlm.js/tree/master

tuttavia credo che andando giù questo metodo per il single sign on sta per essere frustrante nel lungo periodo.

Abbiamo finito per eseguire l'autenticazione NTLM in un iframe nascosto e accedere all'iframe tramite javascript.

+0

Questo è un bene, nota: non c'è un modo per fare CORS (o JSONP) utilizzando questo per quanto posso dire. – Gram

0

Non è necessario rispondere alla richiesta di autenticazione NTLM (Autenticazione integrata di Windows), il browser deve eseguirla automaticamente, se configurata correttamente. Probabilmente sono anche numerose altre complicazioni.

Fase 1 - Browser

Verificare che il browser possa accedere e inviare le proprie credenziali con un'applicazione web NTLM o premendo il software che si sta sviluppando direttamente prima.

Fase 2 - JavaScript withCredentials attribuiscono

L'errore 401 non autorizzato ricevuto ed i sintomi descritti sono esattamente la stessa cosa quando non ero riuscito a impostare l'attributo 'withCredentials' a 'vero'. Non ho familiarità con jQuery, ma assicurati che il tuo tentativo di impostare quell'attributo abbia esito positivo.

Questo esempio funziona per me:

var xhttp = new XMLHttpRequest(); 
xhttp.open("GET", "https://localhost:44377/SomeService", true); 
xhttp.withCredentials = true; 
xhttp.send(); 
xhttp.onreadystatechange = function(){ 
    if (xhttp.readyState === XMLHttpRequest.DONE) { 
    if (xhttp.status === 200) 
     doSomething(xhttp.responseText); 
    else 
     console.log('There was a problem with the request.'); 
    } 
}; 

Fase 3 - lato server abilita CORS (opzionale)

ho il sospetto di una delle principali ragioni per le persone finiscono in questa domanda è che si stanno sviluppando uno componente sulla loro stazione di lavoro con un altro componente ospitato altrove. Ciò causa problemi Cross-Origin Resource Sharing (CORS). Esistono due soluzioni:

  1. Disabilitare CORS nel browser, utile per lo sviluppo quando il lavoro verrà distribuito sulla stessa origine della risorsa a cui accede il codice.
  2. Abilita CORS sul server: è presente un'ampia lettura su Internet più ampia, ma ciò implica fondamentalmente l'invio di intestazioni che abilitano CORS.

In breve, per consentire CORS con le credenziali è necessario:

  • Invia un '-Control-Allow-Origin Access' intestazione che corrisponde l'origine della pagina servito ... questo non può essere '*'
  • Invia un 'Access-Control-Allow-credenziali' con il valore 'true'

Qui è il mio codice di lavoro .NET di esempio nel mio file Global.asax. Penso che sia piuttosto facile vedere cosa sta succedendo e tradurre in altre lingue, se necessario.

void Application_BeginRequest(object sender, EventArgs e) 
{ 
    if (Request.HttpMethod == "OPTIONS") 
    { 
     Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     Response.End(); 
    } 
    else 
    { 
     Response.AddHeader("Access-Control-Allow-Credentials", "true"); 

     if (Request.Headers["Origin"] != null) 
      Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]); 
     else 
      Response.AddHeader("Access-Control-Allow-Origin" , "*"); // Last ditch attempt! 
    } 
}