Getting HttpCurrent info through web service

Getting HttpCurrent info through web service

Old forum URL: forums.lhotka.net/forums/t/2410.aspx


ltgrady posted on Thursday, February 22, 2007

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

RockfordLhotka replied on Thursday, February 22, 2007

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.

ltgrady replied on Friday, February 23, 2007

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.

ltgrady replied on Friday, February 23, 2007

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

RockfordLhotka replied on Friday, February 23, 2007

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