2012-06-20 18 views
22

Sto tentando di accedere a una pagina Web su uno stesso dominio/stessa applicazione asp.net, che è protetta da password. Le credenziali sono le stesse sia per la pagina Web che attiva questa chiamata sia per la pagina web a cui si accede.WebClient che accede alla pagina con credenziali

Questo è il codice e non so perché ho sempre un codice html di accesso al modulo?

using (WebClient client = new WebClient()) 
{ 
    client.QueryString.Add("ID", "1040"); //add parameters 
    //client.Credentials = CredentialCache.DefaultCredentials; 
    //I tried to add credentials like this 
    client.Credentials = new NetworkCredential("username", "password"); 

    string htmlCode = client.DownloadString("http://domain.loc/testpage.aspx"); 
} 
+0

Perché non stai semplicemente reindirizzando a quella pagina? Scaricarlo utilizzando il codice nel processo del server significa che * non * sta utilizzando le stesse credenziali. Se capisco correttamente, piuttosto che il browser (con le credenziali del cliente) che accede alla pagina, un processo diverso su una macchina diversa (il server) lo sta scaricando e presentandolo al client! – shambulator

+0

Come vengono fornite tali credenziali alla pagina Web? Utilizza l'autenticazione basata su form? –

+0

@shambulator Che cosa intendi per reindirizzare a quella pagina? Sto cercando di ottenere il codice html di quella pagina. – mko

risposta

48

Sospetto che la pagina Web a cui si sta tentando di accedere utilizzi Autenticazione moduli. Ciò significa che dovrai fornire un cookie di autenticazione valido se desideri essere in grado di accedere a risorse protette. E per ottenere un cookie di autenticazione valido dovrai prima autenticarti inviando una richiesta POST alla pagina LogOn che emette il cookie. Una volta recuperato il cookie, sarai in grado di inviarlo insieme alle richieste successive su risorse protette. Si dovrebbe anche notare che la scatola WebClient non supporta i cookie. Per questo motivo si potrebbe scrivere un cookie personalizzato consapevoli client Web:

public class CookieAwareWebClient : WebClient 
{ 
    public CookieAwareWebClient() 
    { 
     CookieContainer = new CookieContainer(); 
    } 
    public CookieContainer CookieContainer { get; private set; } 

    protected override WebRequest GetWebRequest(Uri address) 
    { 
     var request = (HttpWebRequest)base.GetWebRequest(address); 
     request.CookieContainer = CookieContainer; 
     return request; 
    } 
} 

Ora si potrebbe usare questo client di sparare le 2 richieste:

using (var client = new CookieAwareWebClient()) 
{ 
    var values = new NameValueCollection 
    { 
     { "username", "john" }, 
     { "password", "secret" }, 
    }; 
    client.UploadValues("http://domain.loc/logon.aspx", values); 

    // If the previous call succeeded we now have a valid authentication cookie 
    // so we could download the protected page 
    string result = client.DownloadString("http://domain.loc/testpage.aspx"); 
} 

Ovviamente a causa della crapiness ViewState di ASP.NET potrebbe essere necessario inviare un paio di altri parametri lungo la richiesta di accesso. Ecco cosa potresti fare: autenticarti in un browser web e guardare con FireBug i parametri esatti e le intestazioni da inviare.

+0

La soluzione sembra carina e pulita. I nomi per la raccolta di login dovrebbero essere davvero nome utente e password? E c'è un modo diverso per l'applicazione di utilizzare le credenziali correnti nonostante il fatto che sia basata su moduli.? – mko

+0

@ John, non so se i nomi per il login dovrebbero essere nome utente e password. Dipenderà interamente da come viene implementata la pagina di accesso e dai parametri che si aspetta. E, no, non c'è altro modo. È necessario ottenere un cookie di autenticazione dei moduli valido e l'unico modo per ottenere tale cookie è fornire credenziali corrette alla pagina di accesso. È solo questa pagina (si spera :-)) che emette i cookie di autenticazione delle forme. Il codice –

+0

non funziona, ma capisco l'idea e cercherò di farlo funzionare. – mko