Manish Jain
Manish Jain

Reputation: 9649

UserNamePasswordValidator and Session Management

I'm using WCF custom Validator with HTTPS (.NET 4.5). Validate on success returns Customer object which I would like to use later. Currently I'm able to do it with Static variables which I like to avoid if possible. I tried to use HttpContext which becomes null in main thread. My understanding Validate runs under different thread. Is there any way I could share session info without involving DB or File share. See related threads here and here.

In Authentication.cs

public class CustomValidator : UserNamePasswordValidator
{ 
      public override void Validate(string userName, string password)
      {
       //If User Valid then set Customer object
      }
}

In Service.cs

  public class Service
  {
      public string SaveData(string XML)
      {
       //Need Customer object here. Without it cannot save XML. 
       //HttpContext null here.
      }
  }  

Upvotes: 0

Views: 1144

Answers (2)

Manish Jain
Manish Jain

Reputation: 9649

Alright this should have been easier. Since the way UserNamePasswordValidator works, I needed to use custom Authorization to pass UserName/Password to the main thread and get customer info again from the database. This is an additional DB call but acceptable workaround for now. Please download code from Rory Primrose's genius blog entry.

Upvotes: 0

Chandermani
Chandermani

Reputation: 42669

I can suggest you an alternative approach. Assuming that the WCF service is running in ASP.Net compatibility mode and you are saving the customer object to session storage. Create a class such as AppContext

The code would look something like this

public class AppContext {
public Customer CurrentCustomer {
  get {
    Customer cachedCustomerDetails = HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
        if (cachedCustomerDetails != null)
        {
            return cachedCustomerDetails;
        }
        else
        {
            lock (lockObject)
            {
                if (HttpContext.Current.Session[CUSTOMERSESSIONKEY] != null)        //Thread double entry safeguard
                {
                    return HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
                }

                Customer CustomerDetails = ;//Load customer details based on Logged in user using HttpContext.Current.User.Identity.Name
                if (CustomerDetails != null)
                {
                    HttpContext.Current.Session[CUSTOMERSESSIONKEY] = CustomerDetails;
                }

                return CustomerDetails;
            }
        }
  }
}

The basic idea here is to do lazy loading of data, when both WCF and ASP.Net pipelines have executed and HTTPContext is available.

Hope it helps.

Upvotes: 1

Related Questions