views:

54

answers:

0

I am trying to connect to a secured ASMX web service over HTTPS using Silverlight 4.

When I add the web service reference I get challeged for credentials and I get warned that those credentials will be sent in clear text over the network; however, since the data is transported over HTTPS this should not be a concern.

The resulting ServiceReferences.ClientConfig file contains the following binding:

        <basicHttpBinding>
            <binding name="webServiceName" maxBufferSize="2147483647"
                maxReceivedMessageSize="2147483647">
                <security mode="Transport" />
            </binding>
        </basicHttpBinding>

In code, I do the following:

        var client = new webServiceClientClass();
        client.ClientCredentials.UserName.UserName = username;
        client.ClientCredentials.UserName.Password = password;
        client.webServiceMethodCompleted += 
            new EventHandler<webServiceMethodCompletedEventArgs>(client_webServiceMethodCompleted);
        var startTime = DateTime.Now;
        var state = new ServiceState()
        {
            StartTime = DateTime.Now,
            Id = id,
        };
        client.webServiceMethodAsync(id, state);

Executing this code in the browser challenges the end-user for credentials. If the end user enters the credentials correctly everything works fine; however, the end user is not supposed to know the credentials for the web service.

For testing purposes, I am trying to retrieve the String coming from the web service URI (the descriptive page and the WSDL), using the following code:

        WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);

        string usernamePassword = String.Format("{0}:{1}", username, password);
        var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(usernamePassword));
        authorizationHeader = String.Format("Basic {0}", authorizationHeader);


        WebClient authorizationClient = new WebClient();
        authorizationClient.Headers[HttpRequestHeader.Authorization] = authorizationHeader;
        authorizationClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(authorizationClient_DownloadStringCompleted);
        authorizationClient.DownloadStringAsync(new Uri(webServiceUriString));

This code executes successfully, and the end user does not get challenged for credentials. I obtain the downloaded HTML and WSDL.

For testing purposes I have also used a wrong username and/or password, and in that case I get the following exception:

System.Net.WebException: The remote server returned an error: NotFound.

Which means that the authentication is indeed happening.

Since client.ClientCredentials.UserName did not work, I have tried to do it in other ways, but I haven't been able to dig deep enough to get a hold of the HttpWebRequest that the service proxy is using in order to inject the authorization header on it.

Does anyone know if it is possible to reproduce the authentication methodology that is successfully used for the web client on the web service proxy?