I just started using WCF Services with ASP.NET AJAX. I instantiate my WCF service from Javascript and then pass string variables as arguments to my WCF Service method (with an OperationContract signature). I then return a .NET object (defined with a DataContract) which is bound to my custom Javascript class. I'm having trouble authenticating based on the user logged into my web session. However, the WCF web service is a completely different service with no context to the HttpContext.Current object. What is the most secure way to get access to that object?
Wcf – access HttpContext.Current from WCF Web Service
httpcontextservicewcf
Related Solutions
This is a very reasonable approach.
To do this you setup your service endpoint and configure it with your custom membership provider (You can do the same with SQL membership provider, it doesn't require a custom one).
On the web application you set up the Authenticate event of the Login control to instantiate a new service proxy and set the username/password in the ClientCredentials in the proxy.
Now when you make the call to the Service through the proxy WCF will pass these credentials through the secure channel to the service and use them for authentication.
Now you simply need to store the proxy in session and use it for future access to the service as it has the channel state and a private key.
protected void LoginControl_Authenticate(object sender, AuthenticateEventArgs e)
{
bool Authenticated = false;
try
{
MyServiceClient proxy = new MyServiceClient("MyServiceEndpoint");
proxy.ClientCredentials.UserName.UserName = LoginControl.UserName;
proxy.ClientCredentials.UserName.Password = LoginControl.Password;
//It doesn't really matter what is called or what it does because
//Membership Provider for the Service does the authentication.
string retval = proxy.login("Logging in");
//Now that channel is established the proxy needs to be kept
//since it contains the channel state which includes a private key
Session["MyServiceProxy"] = proxy;
Authenticated = true;
}
catch (Exception ex)
{
//Login Error...
}
e.Authenticated = Authenticated;
}
One word: DON'T !
Services should be stateless whenever possible - it makes life just that much easier.
If you need to keep state between calls, put it in a persistance container, e.g. a database, and report back the ID under which it can be found for the next call.
Marc
If you really must keep session (really?? Think about it twice - better yet: three times) - then WCF offers per-session calls on certain bindings (protocols).
The basicHttpBinding
which is closest to ASMX webservices for one does not support sessions. You'll need to use wsHttpBinding
for internet-facing apps, or netTcpBinding
for internal intranet-oriented services.
Check out the MSDN docs on using sessions with WCF.
Best Answer
You can get access to
HttpContext.Current
by enabling AspNetCompatibility, preferably via configuration:That in turn allows you to get access to the current user:
HttpContext.Current.User
- which is what you're after, right?You can even enforce AspNetCompatibility by decorating your service class with an additional attribute:
(In the
System.ServiceModel.Activation
namespace.) If that attribute is in place, your service will fail to start unless AspNetCompatibility is enabled!