I am creating a Silverlight with WCF connectivity. I would like to create and maintain a session after user login in Silverlight and do the following.
- On successful login, create a session object and store session id, user id, user name, session status
- On further calls with WCF, the session information needs to be passed from Silverlight to WCF
One solution would be to create a session object and pass it as parameter to all methods.
Is there any other way of passing the info in all web service calls without passing a member variable?
Something similar to persistent Session object in ASP.NET.
Why would you want to pass the session information each time?
If you're using ASP.NET to host your WCF service in ASP compatibility mode, you can set the instanciation mode to Session to then store all that in your WCF service instance variables. Or in your ASP session object.
I can't see what your point is in sending all this data for each request.
A good thing to do when using SL with ASP.NET is to login using the ASP.NET built-in authentication Like here and then you can just call the WCF service and check that HttpContext.Current.User.Identity.IsAuthenticated
is true.
Sessions are automatically handled for you if Cookies are enabled in your browser. Simply add an empty Global.asax file to your web application and a session will get created automatically on first browser request.
Hm.. you can use DB to help you to do that..
this is the thing...
- Silverlight APP send authenticate to wcf login service
- WCF login service validate and create session in your db session
- WCF login will return true on successful login and false in unauthorizedlogin
- Silverlight App store global login variable for latter use
- Now you have the information in your apps and on your server :)
Next problem:
1. How to delete the session in server?
* just create log out button and call the service to remove your session in database
* and remove your global variable for your apps (session variable/login variable)
How if the user doesn't click logout button?
- on the server site just do some periodically active session checking. If it is not active anymore, remove it.
Basically, you must send your session id over internet to call all of your service to confirm that you are authenticated user :)
Notes:
Well, there is no other way, since service is stateless.
Okay first of, silverlight is not asp.net, WCF by design is stateless, unless otherwise constructed to keep state.
Then if you want to keep state in silverlight 3, you could just create a static class with static properties and maintain these values across pages. But this is not an elegant solution. This is possible since SL is a clientside runtime, and your app exists within a xap assembly that is downloaded when you navigate to the url, so basically its like having a windows desktop app downloaded then running in a restricted security context. I dont want to get into the implications of this now, but its important you know this exists.
A better way to solve your problem is to use the IsolatedStorage like so
IsolatedStorageSettings.ApplicationSettings.Remove("UserName");
IsolatedStorageSettings.ApplicationSettings.Add("UserName", UserName);
IsolatedStorageSettings.ApplicationSettings.Remove("Password");
IsolatedStorageSettings.ApplicationSettings.Add("Password", UserPassword);
By doing this you could actually save data to the applicationsettings and re-use it on the next time the application is started. Remember everything stored in the IsolatedStorage is basically cleartext, accessible only from the same domain/site.
You must secure your WCF service using one of the many security schemes available otherwise, the information SL3 transfers to the WCF service will be in cleartext and readable by anyone who puts in a little effort, and anyone can call your wcf service bypassing your SL app completely, so remember to properly secure everything.
WCF authentication in silverlight is performed via SOAP headers which you don't have access to - you can't pass authentication information from Silverlight to WCF as requested. Assuming you're using ASP.NET Application Services to perform user authentication (it's the only tech I know of that'll work here) your basic strategy could be to call the ValidateUser method, which will perform a login and instruct the Silverlight control to include that user session info in the SOAP headers, then make calls to WCF services. You can either periodically refresh the session by logging the user in behind the scenes or wait for a WCF call to fail based on credentials and then validate the user again. I don't know if there's some keep alive aspect to calling WCF services that may make the need to re-authenticate less pressing.
You can store the user's login and password in isolated storage as suggested by another poster, but make sure you encrypt that data first, it's stored in plain text in an obscure location and is not safe.
The end goal is just to temporarily store the user's variable as long as their browser is open. Regardless of elegence, if it's not megabytes of data, I just temporarily store them in a variable or Resource in memory in the app or class so you don't have to worry about it showing up locally on their machine. It will be gone when the browser session is over.
App.Current.Resource.Add("MySessionItem", item)
For the WCF call, try to let ASP.net do the authenication for you with ASP.net Application Services (i.e My.User.Identity), don't authenticate in your WCF methods based on those passed parameters your storing in the temp variable and/or resource.