I'm using the code below from this post to try and create a custom http module :
public class BasicAuthenticationModule: IHttpModule
{
public void Init(HttpApplication application)
{
application.AuthenticateRequest += new EventHandler(Do_Authentication);
}
private void Do_Authentication(object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
string header = request.Headers["HTTP_AUTHORIZATION"];
if(header != null && header.StartsWith("Basic "))
{
// Header is good, let's check username and password
string username = DecodeFromHeader(header, "username");
string password = DecodeFromHeader(header, password);
if(Validate(username, password)
{
// Create a custom IPrincipal object to carry the user's identity
HttpContext.Current.User = new BasicPrincipal(username);
}
else
{
Protect();
}
}
else
{
Protect();
}
}
private void Protect()
{
response.StatusCode = 401;
response.Headers.Add("WWW-Authenticate", "Basic realm=\"Test\"");
response.Write("You must authenticate");
response.End();
}
private void DecodeFromHeader()
{
// Figure this out based on spec
// It's basically base 64 decode and split on the :
throw new NotImplementedException();
}
private bool Validate(string username, string password)
{
return (username == "foo" && pasword == "bar");
}
public void Dispose() {}
public class BasicPrincipal : IPrincipal
{
// Implement simple class to hold the user's identity
}
}
The code works ok at making the 401 error be returned by the server and the login dialog pop up but when the correct login details are entered the login dialog does not go away.
When debugging the code nothing happens when the Ok button on the dialog is clicked, the event isn't triggered and the user details aren't validated, I can't figure out why this isn't working.
Any help or ideas would be great, thanks.
On Microsoft's asp.net website, there is a good example on how to do custom authentication. Ignore the fact that it says it's about WebAPI. The code uses a IHttpModule, so it works with WebForms, IHttpHandler, asmx, WCF, and anything else that runs in IIS. Copying and pasting the code at the end of that page into a new project works for me. Although, I don't recommend setting the thread's CurrentPrincipal to the authenticated user, like the sample does. I prefer to just use the current context's User property.
If your breakpoint in the module isn't getting hit, then it's almost certainly because the http module wasn't registered correctly. The asp.net page I linked above shows how to register the module in your web.config file, so you should start there. You should be able to use Visual Studio's intellisense auto-complete to complete your class name, which helps make sure you typed it right (although there is a chance that Resharper is doing it on my machine, but I think it's just plain Visual Studio).