Currently in our website we are using 1.) Session 2.) Cookie ; , they both have their own disadvantages. So, in our new website we don't want to use sessions and cookies.
We have googled and find some alternative ways of session and cookie as below:
1.) Use 'Local Storage 'or 'Session Storage'.
2.) Append data with the querystring.
Local storage is client side alternative to session. It will only be available to client script, not the server code, you would use it if you are writing a SPA and plan on making Ajax calls.
So, we need a alternative technical way to handle session and cookie with some other method.
Please help me regarding it .
Use 'Local Storage 'or 'Session Storage'.
Local Storage is not a replacement for Session State. They are totally different technologies.
Append data with the querystring.
QueryString is not a replacement for Session State either. We only use query string to pass very small data (normally integer value) between pages.
So, we need a alternative technical way to handle session and cookie
with some other method.
Cookie
For ASP.Net MVC, you want to use Cookie for authentication unless you want to use Bearer Token. There is nothing wrong with using Cookie for authentication unless you abuse it.
Session State
In a nutshell, we do not need to use Session State directly in ASP.Net MVC. You can say that Session State and View State are somewhat replaced by Model if you will.
Keep in mind that TempData use Session State under the hood.
I have googled to find some resources and trying to find out more, if anyone have suggestions please update.
2 ways to pass data between pages without using Session and Cookie:
1.) using Local Storage
2.) using Secure Query String:
====================================================
1.) using Local Storage:
a.) Local Storage or Session Storage:
What is the difference between localStorage, sessionStorage, session and cookies?
b.) HTML5 offline storage - Alternative to Session? [closed]
HTML5 offline storage - Alternative to Session?
Disadvantages:
Are there any drawbacks to using localStorage instead of Cookies?
2.) using Secure Query String:
a.) MVC Encrypt Query String:
Encrypting an id in an URL in ASP.NET MVC
b.) Securely Passing Identity Tokens Between Websites
http://dotnetslackers.com/articles/aspnet/Securely-Passing-Identity-Tokens-Between-Websites.aspx#1776
c.) Encrypt and Decrypt URL in MVC 4
https://dotnettrace.net/2013/09/19/encrypt-and-decrypt-url-in-mvc-4/
Related
I originally used static variables to store some user information when a user is browsing my site. I had issues where occasionally a user would navigate somewhere and see a different users name on the page. I switched to using session variables to solve this, but the same problem occurred. I then thought making the session variable names unique in some way would solve the problem, e.g. instead of
Session["userId"]
I changed all session variables to append the unique username of the user when they are created and referenced, so they are:
Session["userId" + Context.Identity.User.Name.ToString()]
So far I've had no reports of the issue, but is this actually going to work? Is there a simple way to protect sessions so the variables don't leak between users? I'm confident with ASP.NET code (webforms specifically) but have only encountered the session issue as more users use the site. I don't have much control over IIS settings as the site is built via AWS Elastic Beanstalk, so it's mostly default IIS settings.
This should work fine, but I suggest storing username or user profile information in cookies or local storage since as you mentioned when lot of users logged in it maintains session for them on server memory(I believe session is in-memory by default not in-proc or redis). This is not scalable as if millions of user logged in or you create load test server considerable memory will be taken by session management. Few hundred users however is not much overhead.
You can store information at user browser using sessionStorage like:
Setting value
sessionStorage.setItem("user_name", "test");
Getting Value
var userName = sessionStorage.getItem("user_name");
It can store javascript object or json too.
Cookies are old way to store info at user end :
Creating cookie
document.userCookie = "username=John Doe";
reading cookie
document.userCookie //"username=John Doe"
Forms authentication also provide encrypted & secured cookies which is maintained with session which is also good if user profile information is sensitive data.
Sorry, I can't write comments for your question, but:
Same issue happed to Java developer with AWS Elastic Beanstalk:
https://forums.aws.amazon.com/thread.jspa?threadID=84027
First, I suggest you try to set no-cache for your HttpResponse (temporary solution), than
I suggest you try to play with your IIS proxy settings.
If it didn't help (and you're using load balancer) - refuse from using inproc settings like in this topic:
User on wrong session
PS. You really don't have to make session variable names different - Session uniqueness is guaranteed by ASP.NET setting different Session_ID for each session.
I'm using a login form to authenticate users.
FormsAuthentication is right out as it stores sensitive user/role membership in either client-side in a cookie or within the URL. Within the URL is a huge security risk, so I won't even get into that. With the
FormsAuthentication cookie, this creates problems with a) security where the client is in the position of dictating it's own roles; and b) way too much data stored in cookies. Since I'm gaining nothing through security and loosing out big time on the size of user data storage, I'd rather just work with Sessions.
I'd like to reuse something like FormsAuthentication for all its basic login form-handling features. But i would rather have it store user data server-side in perhaps Session rather than client-side all stuffed into a single cookie. I'd rather just authenticate against a Session token of some sort.
I have no database and local disk storage of user data is forbidden. I rely on a 3rd party authentication service provider, and a requirement is that I must reduce chatter with this service. Thus, sessions for temporary storage of user info. Sucks, but that's not necessarily the problem I'm asking about. Also, a requirement is that I must set/use HttpContext.user and likely Thread.CurrentPrincipal for use later on in such things as AuthorizeAttribute, for displaying user info in views, etc.
So FormsAuthentication stores all user data client-side in a cookie. Whereas Session stores all data server-side and just relies on a simple client-side token cookie. However, Session is not available anywhere during the asp.net startup and authentication steps. Is there an equivalent forms "membership" provider that stores all data in Session server-side instead of client-side?
If there is no Session equivalent...
Where do I set HttpContext.user and Thread.CurrentPrincipal to make both values available throughout the rest of both MVC apps without interfering or messing up other MVC components?
Hinging on #1, is Session available at that entry point? If not, how do I make it available so I can create the Principle/Identity object using the data stored in Session?
This can't possibly be a unique requirement. Are there libraries already available which handle this?
Session stores information in a client-side cookie too! (or in the URL if cookieless).
If you want to authenticate a client, he'll have to provide some kind of credentials - usually an encrypted token in a cookie once he has logged on. If not a cookie, then what do you propose?
You should use FormsAuthentication. The sensitive information stored in a client-side cookie is encrypted using a key that should only be known to the web server. "the encryption methods being public knowledge" doesn't mean that you can decrypt the data without access to the appropriate cryptographic key.
You mention "roles" and a "third-party authentication provider". If your third party is also providing roles (i.e. an "authorization provider" as well as an "authentication provider"), then it would be reasonable to cache roles obtained from the provider on the server. Session is not available when a request is being authorized, so the best solution is to use the Cache (System.Web.Caching.Cache).
Personally I would encapsulate this in a custom RoleProvider. The custom RoleProvider would implement GetRolesForUser by getting roles from the third party on the first call, then caching them in Cache.
Not sure if I like what I'm about to suggest, but you could do the following:
Leverage the Application State or System.Cache as a global storage for user credentials.
Use an InMemory database (like RavenDb) which can also have encryption (in memory, I believe).
Using the Application state as a place to storage relatively common / frequent stuff I think is not a great place because of
Scaling / locking issues? <-- just a gut feeling.
Permenant data? so you have users in the website's memory .. then the website crashes or recycles, etc... what happens now to that data?
RavenDb is awesomeballs - go.use.it.now.
I understand that you are not storing anything locally, so whenever a user hits your system, you need to refresh your inmemory cache, etc. Fine. A pain in the f'ing butt , but fine none-the-less. (EDIT: unless the data has been cached in memory .. that is)
Anywys, two suggestions.
ProTip:
Oh! move away from role based shiz and start using Claims based identity stuff. Yes, it still works with IPrincipal and HttpContext.User, etc. So all previous code is NOT busted. But now it's baked into .NET 4.5
Awesome Video on this for you, me, everyone!
Finally - bonus suggestion
A nice package that auth's with either Facebook/Google/Twitter. You said you're keeping the user cred's on another site (good move!). If you're using other providers, then stick with DNOA or SS.
GL!
Ignore for the moment that not all browsers support LocalStorage.
Would it be possible to roll your own authentication "handler" (for want of a better word) that makes use of LocalStorage rather than a Cookie for FormsAuthentication within an ASP.NET web app?
If it is possible where would I find the best information to start learning how to do it?
Generally, your authentication happens at the server end and cookie contents are passed along with every request. So, by using the information available in request before accessing the resource, server can see if the user is logged in.
But, in case of localStorage the contents are not passed to the server with every request and is accessible only to Javascript. Hence it is not possible to use localStorage for authentication instead of cookie.
Im just wondering how to go about using FormAuthentication in asp.net
In our project we are basing it on webservices, which returns an XML document on successful login with all the credentials we require. Whats the best way to store and access the information returned?
Thanks
EDIT: thanks for the response. I cant use the default provider because the provider is already given to us.
Basically, what I want to know is whats the most effecient way to store a Guid and an Integer on successful login so that it can be easily accessed by my asp.net application.
When you create your FormsAuthenticationTicket, you can set the UserData property to anything you like, including the data from the web service. That data will all be encrypted when placed into the Forms Authentication cookie, and will be decrypted on each subsequent request. The information will be available in the Ticket property of the FormsIdentity object that you can reach via HttpContext.Current.User.Identity.
How to go about it? Its a complex subject which no one can answer fully here.
I can tell you that the easiest way to implement it is to use the standard SQL Server-backed forms authentication provider. This is a step-by-step on how to set it up.
It can get a little confusing when there are database issues, however. These are usually caused by common issues and some googling often straightens it out quickly.
Keep in mind, also, that forms authentication usually entails sending cleartext passwords across the network. So protecting your login URL with SSL is a must in a production environment.
Session["GUID"] = value;
Session["INT"] = value;
Shoving the XML Dom object or xml in the Session object is not advisable for performance reasons when you only need 2 tiny values.
I have two web applications and sometimes I need user to jump from one application to another. Since they are two web applications and may reside on different domains/machines, I can not share session between them.
The technical challenge for me is how to pass session information (I only need to pass userID string information in the session) from one source application to another destination application -- so that the user feels Single Sign On and personal information is displayed for him/her in both application (as the userID is passed to the destination application, no re-login is needed).
My current solution is generate all URL strings in both application and append them with user ID after user logins successfully, like http://www.anotherapplication.com/somepage?userID=someuserID, the userID value is retrieved from session. But I think my solution is stupid and I want to find some way to automatically append the query string ?userID=someuserID when the user jumps to another URL in another application -- so that I just need to generate the common unified URL http://www.anotherapplication.com/somepage in both application.
Is there a solution to automatically append the userID query string?
thanks in advance,
George
Rather than doing it via the Querystring, it might be more maintainable in the long run if you use create a FormsAuthenticationTicket with the required values.
I especially recommend reading Michael Morozov's excellent article on the subject of SSO (Single sign ons).
I do not think it is a good idea to have the user id in query string.
A better idea would be to implement a single-sign on solution. In your scenario, you could do the following:
Whenever one of your applications receive an unauthenticated request, redirect the user back to the other application to a special single-sign-on url.
This page checks whether the user is logged in, and if so, redirects back with an authentication token in querystring.
This token is checked by the un-authenticated application; and if it passes, you can login the user.
Of course, this seems like "a lot" of redirecting, but it should be reliable, and it only happens once, and then your user will be authenticated on both applications.
Obviously you would need to implement a security scheme so that you can check that the authentication token you get passed is really valid and originating from your other application. You could do this with a challenge-response algorithm; which could be:
Both applications should know a common key.
First application sends some random data (the "challenge") to the second application.
The second application includes a hash-value of the random data + it's answer + the secret key in its response.
Now the first application can check that the second application knew the secret key by calculating the same hash-value.
Have a look at:
http://en.wikipedia.org/wiki/Challenge-response_authentication
EDIT:
With regards to session state, see http://msdn.microsoft.com/en-us/library/ms178581.aspx for an overview. It is possible to share session state between the applications, but I would not recommend it in general. If your application resides on different domains (URLs) you would have to use cookieless session state; which is not safe. If you decide to go this way, you would either have to use State server or SQL Server for session persistence, depending on your setup.
You can persist the session using something else than InProc (which is short for in process). If you persist the session using a SQL Server backend you'll be able to retrive the session cross domain/machine if they are setup to use the same SQL Server backend for session storage. This is configurable in ASP.NET and support out-of-the-box. I suggest you look it up.