.NET HTTP Module – sample code
In my last mini-article on web services security, I talked a bit about using HTTP authentication mechanisms for web services. I pointed out that it is not necessary to use Active Directory for this, and mentioned that the required code was not all that difficult. I got a number of e-mails from people asking for examples; so in response, here is a fully working sample in 100% managed code demonstrating the use of HTTP Basic authentication, using a separate credential store (in this case, a XML file, although this would be easy to change to a database or LDAP store).
If you find this post useful, please support this site and go buy yourself something on Amazon.com!
Note – an ISAPI filter is an equally effective way to implement this; however, many people have hosting arrangements set up such that they cannot install filters. The code here will work in even a very restrictive shared hosting environment.
The implementation was designed with web services in mind, but it will work equally well with any .NET web application. Also, the user credentials are stored in a XML file (users.xml by default). In a real application, you will probably want to change this to access a database, or wherever else you store user information.
A link to download the code is at the end of this article. Rather than walk through all of the code (it’s pretty self-explanatory, download it and take a look), I will walk through here how to set it up and get it running.
To set up:
1. Build BasicAuthMod.dll, and copy it to your web application’s bin directory on your server.
2. Make the following changes to your web.config file (in the <system.web> section):
- Change authentication line to: <authentication mode=”None” />. We need to disable the built-in ASP.NET authentication.
- Add an authorization section if you wish, such as <authorization>
<deny users=”?” />
If you use BasicAuthMod to authenticate, you can still leverage the built-in ASP.NET authorization capabilities.
- Add the following lines to wire the BasicAuthMod.dll into the ASP.NET pipeline. <httpModules>
3. Make the following changes to your web.config file (in the <configuration> section), and edit appropriately:
4. Copy the sample users.xml file into your virtual directory.
The last thing you need to do is make sure all IIS authentication mechanisms (Basic, Integrated, and Digest) are turned off, and only anonymous is enabled. You can do this within the IIS Manager, or typically hosting providers will provide a way to make sure that Basic is turned off for your hosted sites/virtual directories.
That’s all there is to it; just copy the code, and make some web.config changes. If you have any questions, please feel free to contact me at firstname.lastname@example.org.
[related: Digest authentication sample]
Pingback: Custom data source for Google Earth | Philosophical Geek
This work fine within Visual Studio but does not work in IIS. When we host this on IIS .. IIS does not calling BasicAuthenticationModule (on security tab checked Basic BasicAuthentication only all other options are uncheck )
I think you’ve misread the notes.
>>The last thing you need to do is make sure all >>IIS authentication mechanisms (Basic, >>Integrated, and Digest) are turned off, and only >>anonymous is enabled.
all auth options off, save for anonymous, in IIS.
It strikes me that having basic authentication enabled in IIS would cause the behaviour you noted (your auth module never being called)
I could be wrong… =)
That appears to have secured my web service, but how do I pass the username and password when consuming the webservice say from a VB windows application.
The sample code provided compiles and all but it does not secure my webservice.. Please advice how do I confirm that web-service is secured
@Learner – make sure you follow _every_ step above, including the part after step 4 about IIS config. Then, try to hit your web service endpoint with a browser – you should find that it prompts you for credentials.
I simply cannot get this to work in an ASP.net 2 webservice. It blows up completely inexplicably with w3wp.exe exceptions in the Application Log on Windows 2003 server. HTML pages work just fine, but any time I touch an ASPX or ASMX, the entire app pool crashes.
Pingback: Basic authentication utilizzando uno store diverso da windows - Alessandro Damiani Blog
Using this code and it works great, thanks. Just one question – how would I implement a logout function? I’ve tried FormsAuthentication.SignOut(), Session.Abandon() and Context.User = null, but neither seems to work. I’m stilled logged on as the original user.
Kim – you pretty much can’t…using Basic auth, the browser will re-present the credentials on each request as necessary, and assuming those credentials are still valid, it will be transparent to the user.
This works great on my dev machine with IIS5 but when running on the hosting server (IIS7) it does not work, access is denied all the time.
Where is the link to download the dll
Mike, the source is available, which you can compile. I don’t have a DLL available for download.
I did all the steps , added
using System.Web in the BasicAuthenticationModule.cs Class however visual studio gives errors like IHttpModule, HttpApplication could not be found.. Could you tell me where did i make the mistake?
For anyone trying to get this to work with IIS7, you need to do this:
– In web.config, change the name of the httpModule to “CustomBasicAuthenticationModule”. In IIS7, there’s already a built-in module named “BasicAuthenticationModule”.
– Follow the instructions here http://bdotnet.in/blogs/navaneeth/archive/2008/07/06/2056.aspx
I have hosted this.and webservices working fine with Basic Authentication Module.
My problem is, i hosted web forms also in the same domain.
this authentication working not only for web services but also for web pages also.
i want this should work only foe webservices.is there a way.
Post looks old but I hope still active users out there!
I need a solution like this to support protecting all webs on an IIS7 Server 2008 64 bit box that functions as a QA server. The ISAPI method is required because I need it to work for classic ASP, .net 1.1 and .net 2.0+ web apps.
Has anyone got this to work on a 64 bit machine?
I know that Helicon APE only supports .net 2+ and IISPassword does not work with IIS 7. Others don’t work with 64 bit.
Thought I’d check before I dove in. Prefer a paid / stable solution if anyone knows of one that works in the above described environment!
Pingback: Event Log Monitoring with RSS | Greg Reinacker's Weblog
Pingback: Android – Ksoap2 Authentication in .Net Web Service - Applerr.com All about Apple Products - Applerr.com All about Apple Products
Thanks for your great article.
I have this up and working fine but there is one area which I am hoping you might be able to advise on please.
I need to call my newly restricted webservice through an application which requires basic authentication. I can see from the server logging behind the app, that it is trying to call the webservice as follows: https://username:password@server/webservicename/operation.asxm?wsdl
This does not seem to work though and when I contacted the vendors of the application they said that this is the only way that their system will authenticate.
Would you know is there something that I could change in the BasicAuth.cs or web.config which would get this to work? If I just put in my WSDL address, so https://server/webservicename/operation.asxm?wsdl – it prompts for a username and password and works fine. Its just trying to pass in the details in the format which my application requires that I run into problems. I basically get a 401 error through the application and when trying this in a web browser I get ‘Invalid Syntax Error’.
Any advice would be much appreciated.
Just a note, typo above ‘asmx?wsdl’ rather than ‘asxm?wsdl’ thanks.
I am running your code with few changes after converting it to .Net 4, I can run the application perfectly fine on local machine.
However when I deploy this web service on Dev Environment and call my service in internet explorer. That gives me user prompt; I enter valid username/password but it keeps prompting me username/password, eventually after three tries I get Error message 401.2 – access is denied.
In my HttpModule every time User is authenticated, I log if authentication was successful. And I can see in log file, all three times authentication was successful. But it still error out. :(
By the way If I run web services in Integrated mode, it works fine. Unfortunately my requirement is to run web services in Classic mode.
Environment Details: Windows Server 2008 R2, IIS7.5 Classic mode
I am stuck with this from last 4 days. Please help!
I know its been a while, but did you solve this issue? I am having the same problem as you but it happens when I run locally after converting the project to .NET 3.5. When I run it, I use some credentials from the XML file and it is continuously prompting me for the credentials.
To get this working in IIS 7 I renamed the “BasicAuthenticationModule” httpModule to “CustomBasicAuthenticationModule” as suggested by Chinh
and ALSO had to copy this module from system.web / httpModules into system.webServer / modules
IIS 7 did not seem to pick it up under httpModules (although it did work from development server in Visual Studio).
Same as “Katja” I have tried it for IIS 7.5 and found it working very well. Thanks to “Chinh” and of-course Greg.. Thank you very much..
Nice little module! One suggestion though, I’d rename users.xml to users.config, so you can’t just download the file :).
is it possible to get it work against an LDAP ( such as oracle’s OID) ?
Thank you! works great. I have a question about roles – where can I add code to make sure certain role provides access to a certain webservice method ?
The link is not active anymore . Can someone post the steps to make this work in II7.
Thank you! I wish I’d found this years ago. I’ve been working around bugs in Plesk’s implementation of HTTP authentication for longer than I care to admit.
Do you have code for sample client? Would like to understand how to pass username and password.