Jon Skeet [C# MVP] wrote:
I've run against a problem which I'm *sure* must be easy to solve - but
I'm blowed if I can find the answer :(
I have a web service which I want to require authentication. I need to
authenticate using a database lookup, so Windows, Passport and Forms
authentication are (as far as I can tell) no good to me.
I don't need impersonation.
I would like to use HTTP basic or preferrably digest authentication -
and this is from a Pocket PC Compact Framework client, if that makes
any odds. If necessary, I can write my own custom authentication module
for the client to use non-standard headers if that helps, but obviously
I'd rather not. (I *think* I know how to do that, admittedly.)
My problem is working out what to do on the server side. I basically
need to intercept the request at the point of authentication, and
insert my own authentication module at that point. I *suspect* I need
to implement IHttpModule, but I'm not sure. If I do, I've no idea where
to put anything to use it.
This must be simple, as it's no doubt a very common requirement. Anyone
care to put me out of my misery?
We do this using Windows Authentication with our security data stored in
a SQL server database. On the server we create our own principal object
that inherits from WindowsPrincipal. In Global.asax in the
AuthenticateRequest handler we replace the HttpContext.Current.User with
our principal object, passing HttpContext.Current.User.Identity as
WindowsIdentity to the constructor. Our principal object overrides the
two overloads of IsInRole to use our own security check. We have also
added a HasPermission method to our principal so we can demand a
permission whenever we need to. So our AuthenticateRequest handler
looks as follows:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// this will throw an exception if windows auth not turned on
// Also note we have to set the context here since ASP.NET will take
// what's in the context and place it on the Thread.CurrentUser property
CustomServerPrincipal princ = new CustomServerPrincipal as
WindowsIdentity);
HttpContext.Current.User = princ;
// verify that this user is authorized to get into Polaris
if (!princ.HasPermission(authUserPerm))
{
throw new
CustomSecurityException(String.Format(securityExce ptionMessage,
princ.Identity.Name));
}
}
In any server side objects where we need to demand a permission, we now
simply take the current principal from the thread as our custom
principal and demand the permission. Ex:
CustomServerPrincipal principal =
System.Threading.Thread.CurrentPrincipal as CustomServerPrincipal;
if (!principal.HasPermission(deletePermission))
{
throw new CustomSecurityException(principal, deletePermission);
}
--
Tom Porterfield