2009-04-20 6 views
6

Ich habe eine grundlegende ASMX-Dienst, den ich versuche zu laufen (ich würde lieber WCF verwenden, kann aber nicht den Server damit arbeiten). Es läuft gut in einem keine Sicherheitseinrichtung, aber sobald ich die Sicherheit einschalte, bekomme ich:ASMX Benutzername und Passwort Sicherheit

Die HTTP-Anfrage ist nicht autorisiert mit Client-Authentifizierungsschema 'Anonymous'. Der vom Server empfangene Authentifizierungsheader war 'Basic realm =' Secured area ''.

Was ich will, ist eine minimalistisches die Benutzer für einen Namen und ein Passwort Typen Lösung fragen.

Um den Code mit Intellisense herumzustochern kommt nichts, was aussieht, als ob ich brauche.

This sieht aus wie es könnte nützlich sein, aber es scheint WCF zu sein, also wer weiß.


ich, dass ich nur realisiert diese eine Live-Demo machen:

hier ist der Service: http://smplsite.com/sandbox3/Service1.asmx

der Benutzername ist testapp und das Passwort ist testpw. Ich brauche eine Befehlszeilen-App, die Funktionen für diesen Dienst aufruft.

Befor ich Sicherheit hinzugefügt, diese Linie in einem Grunde VS Projekt arbeitete nach Add Web Service Reference auf dieser URL läuft

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

Dies ist mein aktueller Versuch (Das funktioniert nicht)

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")); 
    } 
} 

Bearbeiten: BTW dies ist keine Website oder läuft im Browser, der zugreifende Code ist eine C# Befehlszeile App. Außerdem wird die Authentifizierung von einem anderen IIS-Plug-in ausgeführt, das ich nicht kontrolliere.

Bearbeiten 2: Um klar zu sein; Die Lösung, nach der ich suche, ist ein rein clientseitiges Problem.

Bearbeiten 3: die Zugangskontrolle ist über eine .haccess Art von System und ich mag es so. Ich möchte nicht, dass der Dienstcode eine Authentifizierung durchführt.

+0

Nach dem Lesen Ihrer Bearbeitung, bin ich nicht sicher, ob meine Lösung hilft, weil das andere IIS-Plugin die Authentifizierung durchführt. Ich lasse es für den Fall, dass es einen Funken zündet ... – Moose

+0

Ich habe meine Antwort bearbeitet. Ich weiß nicht, ob das hilft, aber es ist ein weiterer Versuch ... – Moose

+0

können Sie mit einem Browser zu Ihrem Web-Service gelangen und sehen, was mit fiddler an ihn gesendet wird? Dann können Sie versuchen, die vom Browser verwendete Authentifizierung zu duplizieren. Ansonsten habe ich keine Ideen mehr. – Moose

Antwort

12

Edit:
Wie wäre dies mit:

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

OP sagt wäre dies nicht funktioniert, und jetzt sehe ich, dass es nicht in seiner Situation.

Wir tun etwas wie folgt aus:

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 
     } 
    } 
} 

Beachten Sie, dass IsUserAuthenticated liefern().

Dann ruft der Client es wie folgt aus:

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

bool result = svc.MyWebMethod(); 
+0

Nein, tut mir leid, dass ich nicht das tue, was ich brauche: Soweit ich das beurteilen kann, lehnt IIS den Zugriffsversuch ab und mein Code fängt sogar an zu laufen. Ich denke (und hoffe), dass es die gleiche Art von Mechanismus verwendet, den es für die Zugriffskontrolle mit statischem Inhalt verwenden würde. – BCS

+0

Okay, was ist dann mit der Verwendung der Credentials-Eigenschaft von Ihrem Web-Service-Objekt? – Moose

+0

Ich mache das tatsächlich, funktioniert nicht :( – BCS

2

ich eine neue Antwort hinzufügen werde, weil ich denke, das helfen kann:

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

Ich werde nicht duplizieren es hier, weil ich nichts anderes getan habe, als es zu googeln.

+0

Wenn das richtig benannt ist sieht es wie ich will ... – BCS

+0

Klingt vielversprechend, aber es scheint nicht zu sein, eine GetWebRequest Methode zu überschreiben :( – BCS

+0

Ich kann nicht sehen Web Service, um in Ihre Klassen zu schauen, aber ich habe mir einen hier angesehen, dessen Basisklasse System.Web.Services.Protocols.SoapHttpClientProtocol ist, das eine geschützte Überschreibung hat System.Net.WebRequest GetWebRequest (System.Uri uri) Dies ist die, die Sie überschreiben müssen, oder? – 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> 

beim Verbrauchen

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

Das ausgearbeitet für mich ganz gut.

Verwandte Themen