Greetings:
I am developing an application that uses an ASP.NET Web Forms
application for its UI and ASP.NET web services for its business tier, and I
am looking for assistance in improving my application security. I want to use
declarative security on my web methods so I can secure them more easily. In
short, I want to secure the web services using the first code snippet below.
Please note that the web method has a custom SOAP header. This header
includes three properties, username, password and client id, and currently
provides the mechanism for securing web service access. Each web method
contains code to check the values from the SOAP header against the
application's security metadata. Because of the nature of the application I
cannot use Active Directory - user's must be validated against a database,
and the client id values determines against what database the user name and
password will be validated. I am hoping to avoid the use of procedural code
and to use the PrincipalPermission attribute on my web methods to restrict
access, like so:
[SoapHeader("authHeader")]
[PrincipalPermission(SecurityAction.Demand, Role = "RoleName")]
public DataSet GetUserDetails(...paramlist...)
{
//...
}
This works great, in that the PrincipalPermission attribute is checking
for the specified role, and denying access to the web method. Sadly, it does
this for all users, even those that are members of the appropriate roles - I
cannot figure out how to actually pass a user's credentials along to the web
method from the ASP.NET web forms client application in a manner so that this
actually works. Based on any number of suggestions online, I've tried this in
my client code, to no avail:
UserAdminWS.UserAdmin wsProxy = new UserAdmin();
wsProxy.AuthenticationHeaderValue = new UserAdminWS.AuthenticationHeader();
wsProxy.PreAuthenticate = true;
wsProxy.AuthenticationHeaderValue.clientID = clientID;
wsProxy.AuthenticationHeaderValue.userName = userName;
wsProxy.AuthenticationHeaderValue.userPassword = userPassword;
System.Net.CredentialCache credCache = new System.Net.CredentialCache();
credCache.Add (new Uri(wsProxy.Url), "Basic", new
System.Net.NetworkCredential(wsProxy.Authenticatio nHeaderValue.userName,
wsProxy.AuthenticationHeaderValue.userPassword,
wsProxy.AuthenticationHeaderValue.clientID));
wsProxy.Credentials = credCache;
As far as I can tell, this should work, or at least should be a big part
of the solution, but when I interrogate
HttpContext.Current.User.Identity.Name it always contains the empty string,
and HttpContext.Current.User.Identity.IsAuthenticated is always false. WTF?
I have also tried using the sample code from
http://www.rassoc.com/gregr/weblog/s...Directory.html
and
http://www.rassoc.com/gregr/weblog/s...Directory.html,
but neither one supports passing a third value along with the user name and
password, and without the ability to use the client id any solution is
useless to me.
I'm sure I'm missing something painfully simple, but can't guess what
that might be. Any thoughts or suggestions would be greatly appreciated.
Thanks in advance!
Matthew Roche