views:

1289

answers:

2

I have a basic ASMX service that I'm trying to get running (I'd rather use WCF but can't get the server to work with it). It runs fine in a no security setup but as soon as I turn on security I get:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm="Secured area"'.

What I want is a minimalistic ask the user for a name and password type solution.

Pokeing around the code with intellisense doesn't come up with anything that looks like I need.

This looks like it might be useful but it seems to be WCF so who knows.


I just realized I can make this a live demo:

here is the service: http://smplsite.com/sandbox3/Service1.asmx

the username is testapp and the password is testpw. I need a command line app that calls functions on that service.

Befor I added security, this line worked in a basic VS project after running Add Web Service Reference on that URL

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

This is my current attempt (That doesn't work)

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


Edit: BTW this is not a website or running in the browser, the accessing code is a C# command line app. Also, the authentication is being done by another IIS plug-in that I don't control.

Edit 2: To be clear; the solution I'm looking for is a purely client side issue.

Edit 3: the access control is via a .haccess type of system and I like it that way. I don't want the service code to do any authentication.

+2  A: 

Edit:
How about using this:

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

OP says this wouldn't work, and now I see that it wouldn't in his situation.

We do something like this:

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

Note that you supply IsUserAuthenticated().

Then the client calls it like this:

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

 bool result = svc.MyWebMethod();
Moose
No, sorry that doesn't do what I need: as far as I can tell, IIS is rejecting the access attempt before and of my code even start to run. I think (and hope) it is using the same type of mechanism it would use for access control with static content.
BCS
Okay, then what about using the Credentials Property off your web service object?
Moose
I'm actually doing that, doesn't work :(
BCS
+1  A: 

I'm going to add a fresh answer, because I think this may help:

http://mark.michaelis.net/Blog/CallingWebServicesUsingBasicAuthentication.aspx

I won't duplicate it here, because I didn't do anything but google it.

Moose
If that's named right it looks like what I want...
BCS
Sounds promising but there doesn't seem to be a GetWebRequest method to override :(
BCS
I can't see your Web Service to look inside your classes, but I took a look at one I use here. Its base class is System.Web.Services.Protocols.SoapHttpClientProtocol, which has a protected override System.Net.WebRequest GetWebRequest(System.Uri uri). This is the one you'd need to override, isn't it?
Moose