2009-04-20 41 views
6

Ho un servizio ASMX di base che sto cercando di eseguire (preferisco usare WCF ma non riesco a far funzionare il server). Funziona bene in una configurazione di sicurezza ma non appena accendo la sicurezza ottengo:Sicurezza nome utente e password ASMX

La richiesta HTTP non è autorizzata con lo schema di autenticazione del client 'Anonimo'. L'intestazione di autenticazione ricevuta dal server era "Realm di base =" Area protetta "".

Quello che voglio è un minimalista chiedere all'utente per un nome e una password soluzione tipo.

Puntare il codice con intellisense non crea nulla di ciò di cui ho bisogno.

This sembra che potrebbe essere utile ma sembra essere WCF, quindi chi lo sa.


Ho appena realizzato che posso fare di questo un demo live:

qui è il servizio: http://smplsite.com/sandbox3/Service1.asmx

il nome utente è testapp e la password è testpw. Ho bisogno di una app a linea di comando che chiama funzioni su quel servizio.

Befor ho aggiunto la sicurezza, questa linea ha lavorato in un progetto di base VS dopo l'esecuzione Add Web Service Reference su quel URL

new ServiceReference1.Service1SoapClient().HelloMom("Bob"); 

Questo è il mio tentativo in corso (che non funziona)

class Program 
{ 
    private static bool customValidation(object s, X509Certificate c, X509Chain ch, SslPolicyErrors e) 
    { return true } 

    static void Main(string[] args) 
    { 
     // accept anything 
     ServicePointManager.ServerCertificateValidationCallback += 
       new RemoteCertificateValidationCallback(customValidation); 

     var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 
     binding.Security.Transport.Realm = "Secured area"; 

     // the generated Web Service Reference class 
     var client = new ServiceReference1.Service1SoapClient(
      binding, 
      new EndpointAddress("https://smplsite.com/sandbox3/Service1.asmx") 
      ); 

     client.ClientCredentials.UserName.UserName = "testapp"; 
     client.ClientCredentials.UserName.Password = "testpw"; 

     Console.WriteLine(client.HelloMom("Bob")); 
    } 
} 

Modifica: BTW questo non è un sito Web o in esecuzione nel browser, il codice di accesso è un C# command line app. Inoltre, l'autenticazione viene eseguita da un altro plug-in IIS che non controllo.

Modifica 2: Per essere chiari; la soluzione che sto cercando è una questione puramente client side.

Modifica 3: il controllo di accesso è tramite un tipo di sistema .haccess e mi piace in questo modo. Non voglio che il codice di servizio esegua alcuna autenticazione.

+0

Dopo aver letto la modifica, non sono sicuro che la mia soluzione sarà d'aiuto, perché l'altro plug-in IIS esegue l'autenticazione. Lascerò lì nel caso accenda una scintilla ... – Moose

+0

Ho modificato la mia risposta. Non so se questo sarà d'aiuto, ma è un altro tentativo ... – Moose

+0

puoi arrivare al tuo servizio web usando un browser e guardare cosa gli viene inviato usando il violinista? Quindi è possibile tentare di duplicare l'autenticazione utilizzata dal browser. Altrimenti, sono fuori dalle idee. – Moose

risposta

12

Edit:
ne dite di usare questo:

MyWebService svc = new MyWebService();    
svc.Credentials = new System.Net.NetworkCredential(UserID, pwd); 
bool result = svc.MyWebMethod();  

OP dice che questo potrebbe non funzionare, e ora vedo che non sarebbe nella sua situazione.

facciamo qualcosa di simile a questo:

public class MyWebService : System.Web.Services.WebService 
{ 
    public AuthenticationHeader AuthenticationInformation; 

    public class AuthenticationHeader : SoapHeader 
    { 
     public string UserName; 
     public string Password; 
    } 

    [WebMethod(Description = "Sample WebMethod.")] 
    [SoapHeader("AuthenticationInformation")] 
    public bool MyWebMethod() 
    { 
     if (AuthenticationInformation != null) 
     { 
      if (IsUserAuthenticated(AuthenticationInformation.UserName, 
       AuthenticationInformation.Password, ref errorMessage)) 
      { 
       // Authenticated, do something 
      } 
      else 
      { 
       // Failed Authentication, do something 
      } 
     } 
     else 
     { 
       // No Authentication, do something 
     } 
    } 
} 

Nota che fornite IsUserAuthenticated().

Poi il client chiama in questo modo:

MyWebService svc = new MyWebService();    
svc.AuthenticationHeaderValue = new MyWebService.AuthenticationHeader(); 
svc.AuthenticationHeaderValue.UserName = UserID; 
svc.AuthenticationHeaderValue.Password = Password; 

bool result = svc.MyWebMethod(); 
+0

No, mi dispiace che non faccia quello che mi serve: per quanto posso dire, IIS sta rifiutando il tentativo di accesso prima e il mio codice inizia a funzionare. Penso (e spero) che stia usando lo stesso tipo di meccanismo che userebbe per il controllo degli accessi con contenuto statico. – BCS

+0

Ok, allora che ne pensi di utilizzare la proprietà Credentials dal tuo oggetto servizio web? – Moose

+0

In realtà lo faccio, non funziona :( – BCS

2

ho intenzione di aggiungere una risposta fresca, perché penso che questo può aiutare:

http://intellitect.com/calling-web-services-using-basic-authentication/

io non duplicare è qui, perché non ho fatto altro che google.

+0

Se il nome è corretto, sembra quello che voglio ... – BCS

+0

I suoni promettenti, ma non sembra essere un metodo GetWebRequest per sovrascrivere :( – BCS

+0

Non riesco a vedere il tuo Servizio Web per guardare all'interno delle classi, ma ho dato un'occhiata a quello che uso qui. La sua classe base è System.Web.Services.Protocols.SoapHttpClientProtocol, che ha un override protetto System.Net.WebRequest GetWebRequest (System.Uri uri) Questo è quello che avresti bisogno di sovrascrivere, non è vero? – Moose

0

Config:

<binding name="MyBinding" closeTimeout="00:00:30" 
     openTimeout="00:00:30" receiveTimeout="00:00:30" sendTimeout="00:00:30" 
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferPoolSize="524288" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" 
     textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" 
     messageEncoding="Text"> 
     <readerQuotas maxDepth="32" maxStringContentLength="2147483647" 
     maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="Transport"> 
     <transport clientCredentialType="Basic" realm=""/> 
     </security> 
    </binding> 
    </basicHttpBinding> 

consumando

proxy.ClientCredentials.UserName.UserName = userName; 
proxy.ClientCredentials.UserName.Password = password; 

Questo ha funzionato bene per me.

Problemi correlati