I'm using ASP MVC application + WCF service with custom session behavior implementation. Clients receive, store and use (for authorization) session tokens. Now I'm searching for most secured way to store session token at client side in ASP MVC.
I see few ways:
Hidden field. Drawback: user can open page source code and get token.
Route value. Drawback: token is actually open. User can get it from address bar.
Session. I've read a lot articles with one conclusion: using Session in MVC application is a bad practice. But Session have a lot advantages as well: can be widely
configured, can store token at server side, etc.
I'm sure there are some best practices for solving my problem. Any help will be appreciated.
Require HTTPS connections, encrypt secure data, place in cookie.
You could also pass the token around your site, encrypted of course via a hidden field or something but your scenario is actually what cookies are made to do.
My bank sets a cookie, they should be good enough for what you are doing.
Related
I have been reading a lot about not saving the tokens in the user agent storage and I agree with the risks mentioned.
But going through some of the Auth0 quickstart examples, I see the tokens being saved in the session and using session cookies to track them.
Others mention saving the actual token as an httpOnly cookie with lower risks involved.
My questions are:
How is that considered stateless? especially with scalability and the potential use of load balancers.
Are the alternatives, memory cache and database stores? Is it that any different from sessions?
In the case of SPAs, how to maintain remember me functionality?
Asi Kavindu wrote, localStorage is a good place. If you want to protect the application against XSS attacks, use Content Security Policy, so a browser executes only your JavaScript code. There is a recent RFC about best practices for OAuth 2.0 and Browser-Based Apps, so you can check it.
If you want to keep state (session) on your backend with multiple backend nodes (cluster), you can use some shared data storage such as database or Hazelcast. The architecture is stateful in the same way as a single backend node with an in-memory session.
If you have a session on your backend and a cookie, you don't need an access token anymore, since yor SPA calls just your backend and the token would serve the same purpose as the session ID from the cookie.
The remember me functionality can be implemented using a cookie either at your authentication provider (probably better choice from the security standpoint) or your own application.
Architecture choices are usually trade-offs between simplicity and scalability. If you are just starting developing the application and not sure what to choose, I would go for simplicity, because even if you want to change it later, it should be easier to refactor.
Maintaining a session is applicable only when there is a backend to your application. From purely SPA perspective, storing a token in localstorage is acceptable and relatively secure. Modern browsers have capability to protect loaclsotrage compared to other means.
If you have a backend, correlating access token to a session is better than storing it in a cookie. Also one advantage you get get with this is the ability to get a refresh token, which can be stored in backend.
Having a cookie means loosing statelessness. Cookies are there to maintain a state between server and client end. Session maintaining require server resources but I do not think you need to worry much on that. Scaling must be done targeting your specific requirement.
Remember me functionality is yet again something built with cookies. It is a functionality provided by authorisation server. Think it as your browser remembering your Facebook's logged in status. It uses cookies and your application does not have to worry on that .!
I have an ASP.NET MVC Application and the routing urls looks as follows:
foobar.com/users/8
foobar.com/users/90
foobar.com/exercise/details/5
foobar.com/exercise/details/400
So with this URL route, a user can manipulate the URL directly and change the ID's which are integers. What is the best practice of securing this so that users can't easily manipulate the URL ID's? How do enterprise applications handle this?
For a well designed system, users manipulating URLs should not be an issue. Even if you send the data in an HTTP Post body, users can still manipulate it using an intercepting proxy such as Burp.
Relying on secrecy of IDs (for example, choosing IDs randomly) is also not a solution. In pentester terminology, you will be vulnerable to direct object reference. The classical terminology for this flaw is violation of the complete mediation principle.
Instead of worrying about what users may do with URLs and content sent to your server, you should be securing the server from malicious inputs. The issue here is authorisation. I recommend you have a good, thorough read of Securing your ASP.NET MVC 4 App and the new AllowAnonymous Attribute and NerdDinner Step 9: Authentication and Authorization.
A lot of applications are designed to be URL hackable in that the user can change values. A lot of users like to manipulate the url to change page number, record, etc.
There is nothing wrong with this As long as you make sure its all secure. For instance your Details action should check the user can access record 5 before showing it.
I'm trying to understand how authentication in ASP.NET MVC works. I do not want the built-in MembershipProvider creating a local database behind the scenes. I've also looked at some blog posts talking about custom membership providers. While looking for a much simpler forms authentication model, I found the following:
FormsAuthentication.SetAuthCookie("myusername", true);
FormsAuthentication.SignOut();
The idea is to send the username and salted hashed password to the database and see if they match a record in there. If the user exists, then I pass the username to SethAuthCookie. My questions are:
Should the username be encrypted?
What happens if there are multiple servers and the user is surfing the website? I believe any one of the servers can serve content to the user, so how do they know if the user has been authenticated?
What's the preferred way of authenticating users in MVC without providers? Am I on the right track or should I be looking into something else?
Should the username be encrypted?
No.
What happens if there are multiple servers and the user is surfing the
website? I believe any one of the servers can serve content to the
user, so how do they know if the user has been authenticated?
At each request the server reads the authentication cookie that is sent by the client browser and which was generated by the FormsAuthentication.SetAuthCookie call, decrypts it and retrieves the username that is stored inside. Just make sure that you have set the same machine keys for all nodes of your server farm so that no matter which node emitted the authentication cookie, all other nodes can decrypt it.
What's the preferred way of authenticating users in MVC without
providers? Am I on the right track or should I be looking into
something else?
You are on the right track. You use the FormsAuthentication.SetAuthCookie method to emit the authentication cookie once you have verified that the password hash matches the one of the user in the database and in subsequent actions you could use the User.Identity.Name property to retrieve the currently authenticated user.
I would also recommend you checking out the following article which provides a good overview of how forms authentication works in ASP.NET.
i am writing an asp.net mvc c# site which will not use sessions... What are my options for prividing login functionality without sessions?
System.Web.Security.FormsAuthentication uses cookies:
FormsAuthentication.SetAuthCookie(userName, rememberMe);
No session is used there. Of course, if you want more than a username and isAuthenticated, you'll need some other way to store that state. Your only real alternatives are cookies or the URL, neither one of which are generally acceptable for other reasons.
Session is not evil, especially given your options to host session data on a shared server or on a SQL Server instance.
Session can certainly be abused and your scalability will suffer, but I would not eschew session completely unless there were other overriding concerns.
If you must toss out session entirely, you will have to either recreate state on each call, an expensive proposition generally, or you will have to create your own state storage mechanism which brings us back to standard ASP.NET session storage alternatives.
You basically have 3 options, that I can think of, to authenticate HTTP requests.
1) Cookies only, where you set a cookie on the users machine with the necessary information you need to identify them on their next request
2) Sessions. Session will typically also use cookies (to store session information), but don't have to (see http://msdn.microsoft.com/en-us/library/aa479314.aspx)
3) Stateless authentication. This is really only used for non-browser HTTP clients calling webservices. This includes the client signing the http request with a public/private key combination that the server can then authenticate. An example of a stateless HTTP authentication protocol is OAuth (though OAuth as a spec is really geared towards authorization, but authorization by it's nature requires authentication).
See Web authentication state - Session vs Cookie vs? for additional discussion on Cookies and Sessions.
The common approach is to use cookies. See Securing and ASP.NET MVC Application.
I have reviewed some of the similar questions on this site but could not find one with an answer appropriate for my situation.
I am using asp.net mvc, and it is communicating securely with stateless wcf services. for each service call, i need to pass in the username and a few other ints for identification purposes. - not password, the services are not authenticating.
I am using forms auth to authenticate the users. I am just not sure where, after the user logs in, I should store their username and other account details used for the scope of the user's time logged into the site. suggestions for webforms apps include in "Session". Is there an equivilent alternative in MVC? is storing the info in the forms auth cookie the best solution? it seems like it would be slow to have that info in a cookie as opposed to somewhere else in memory..
thanks
If you need access to a select few bits of information about the current user over and over again, you could combine FormsAuthentication with a custom principal implementation.
The Forms authentication mechanism will write a cookie to your client's disk, and will recreate the custom principal based on that cookie for each call. You could e.g. store something like a user "level", a user "profile" or other small chunks of information, which would then be accessible through the HttpContext.Current.User at any time during the lifetime of your request.
Check out these resources on the topic:
MSDN docs on How to Create a Custom Principal Identity
Using Custom Principal with Forms Authentication in ASP.NET
and I'm sure googling or binging for "ASP.NET custom principal" will render quite a few more hits for you!
yes, unless it's a lot of information, the preferred location is to store it in the cookie. Aside from that, session is the next best place.