We have an ASP.NET (C#) app using CSLA 1.5. When we created the app and our objects we began with the current version and haven't updated yet. Because of our very customized security needs we had to build a custom authorization system. We authenticate using the built in asp.net tools.
So in our login page we use Membership.ValidateUser to validate and then when we call FormsAuthentication.RedirectFromLoginPage we don't create a cookie, and if I remember correctly, the principle object is stored in the session? It's been a while and I didnt' develop that part of the system.
Anyway, a majority of our CSLA BO's use the HttpContext.Current.User.Identity.Name to identify who the logged in user is. That is how we decide which options are available to the user, which brands and products they are allowed to see, to pull up their proposals, etc..
Our problem:
Now we're developing a Web Service. We want to, of course, continue to use our existing CSLA object. This first one is using our ProductSearch object. We're passing in the credential in the SOAP header. Now I can validate the user. However, I can't seem to find the right method or code to get HttpContext.Current.User.Identity.Name to work in my business objects.
If I can get this working everything else will flow. How do I do this?
Thanks, larry
I hate to say it, but relying on HttpContext in a business layer is not a good long-term strategy. While there is an answer to your short-term issue, looking forward to WCF you may not even host in IIS/ASP.NET and so HttpContext won't exist at all.
You are better off, in a business layer, using System.Threading.Thread.CurrentPrincipal.
Or even better is to do what I did in CSLA .NET 2.0 with Csla.ApplicationContext.User, which automatically falls back from one to the other.
In the short term, look at Chapter 10 (in the 1.0 book) at the Login() method I implement in the web service. That sets both the HttpContext and Thread to use the correct principal based on the user's credentials.
Actually our plan is to move to CSLA 2.x and when we do to incorporate/customize the CSLA security framework. I didn't realize until now how limiting HttpContext would turn out to be.
Thanks for the short term solution though, i'll take another look at the chapter and give it a shot.
I think I have this working but it seems a bit too simple. Can anyone reading please take a look and see if there are any problems with doing this the way i'm doing it. Security isn't exactly my area of expertise.
if (UserID == null || Password == null) if (principle.Identity.IsAuthenticated)
{
HttpContext.Current.User = principle;
}
else
{
throw new System.Security.SecurityException("Invalid member, user, or password");
}
}
else
{
throw new System.Security.SecurityException("Invalid member, user, or password");
}
After doing this HttpContext.Current.User.Identity.Name is working in all of my business objects which is what we need right now. I realize that long term this isn't the best solution and we plan on addressing that, however, for this short term need is there anything above that seems foundationally wrong or that would compromise my security?
Thanks, lg
That’s how you do it – not everything has to be hard
J
However, it is very important that you realize that soap headers
are not automatically encrypted or anything. The username/password in the soap
header is in cleartext and can be read by anyone who gets the data stream.
If you want to encrypt it then you need keys on both ends, and
then you have to secure the keys, etc. That gets very hard and messy.
Solutions:
1.
Use SSL (https)
2.
Use WSE 3.0
3.
Use WCF
I don’t recommend trying to write your own key exchange
protocol and everything else that’s required – that’s just
asking for trouble, or at best a false sense of security. Very few people in
the world have fully thought through everything it takes to build that kind of
security, and they are the people who created SSL, WS-Security, etc.
Rocky
From: ltgrady
[mailto:cslanet@lhotka.net]
Sent: Friday, February 23, 2007 10:30 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Getting HttpCurrent info through web service
I think I have this working but it seems a bit too simple. Can anyone
reading please take a look and see if there are any problems with doing this
the way i'm doing it. Security isn't exactly my area of expertise.
if (UserID == null || Password == null)
throw new System.Security.SecurityException("Valid credentials not provided.");
if (Membership.ValidateUser(UserID,
Password))
{
System.Security.Principal.IPrincipal principle = Thread.CurrentPrincipal;
if (principle.Identity.IsAuthenticated)
{
HttpContext.Current.User = principle;
}
else
{
throw new
System.Security.SecurityException("Invalid member, user, or password");
}
}
else
{
throw
new System.Security.SecurityException("Invalid member, user, or password");
}
After doing this HttpContext.Current.User.Identity.Name is working in all of
my business objects which is what we need right now. I realize that long
term this isn't the best solution and we plan on addressing that, however, for
this short term need is there anything above that seems foundationally wrong or
that would compromise my security?
Thanks, lg
Copyright (c) Marimer LLC