ASMX username and password security
Solution 1
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();
Solution 2
I'm going to add a fresh answer, because I think this may help:
http://intellitect.com/calling-web-services-using-basic-authentication/
I won't duplicate it here, because I didn't do anything but google it.
Solution 3
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>
While Consuming
proxy.ClientCredentials.UserName.UserName = userName;
proxy.ClientCredentials.UserName.Password = password;
This worked out just fine for me.
Tjkoopa
For me, fun is taking a program, language, whatever and making it do things it's designer never envisioned it doing. It comes in handy when I'm asked to do something a little outside the norm as part of my job.
Updated on July 09, 2022Comments
-
Tjkoopa almost 2 years
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 istestpw
. 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 URLnew 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. -
Tjkoopa about 15 yearsNo, 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.
-
Moose about 15 yearsOkay, then what about using the Credentials Property off your web service object?
-
Tjkoopa about 15 yearsSounds promising but there doesn't seem to be a GetWebRequest method to override :(
-
Moose about 15 yearsI 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?
-
deanis almost 12 yearsThanks, this AuthenticationHeader idea worked well for me. The only thing is that I couldn't get access to
svc.AuthenticationHeaderValue
. I had to end up callingresult = svc.MyWebMethod(authHeader);
.