I'm currently making a site that is very database oriented somewhat like Stack Overflow. My question is how to handle sessions that will travel across several servers(I plan on using AWS servers for auto scaling).
Currently I am under the belief that I should not use Forms Authentication for scalability and speed purposes. Instead I would have a table in the database called sessions that stores the following information: SessionID, UserID, ExpDate, CreateDate, IP, Status('LogedIn', 'LogedOut', 'Expired').
My biggest concern would be security from the stand point of cookies and not having the experience to see a bottle neck scenario when I have a lot of server running.
Please provide me with your insight. I'd also like to know how others and Stack Overflow are handling this dilemma.
FYI: For the same reasons I'm using PetaPoco instead of Entity Framework as I was able to shave off around 600ms by doing so.
Thank you for your help!
I am not aware of any scalability issues with using Forms Authentication. Essentially, it encrypts an authorization token into a cookie and the cookie is presented to the server on each request. Using cookies instead of in-process session does allow for scalability as it is not tied to any one specific server.
The encryption uses a machineKey value that is stored on the server so breaking the encryption would require getting a hold of the machineKey.
In general, I try not to implement my own authorization and instead try to stick with out-of-the-box solutions that have been tested.
Your approach of using a session store still requires the use of a cookie to store some kind of pointer to the session store. Depending on your implementation, it might be easy to guess this information and easily impersonate someone else.
EDIT:
Since you are running on AWS, I would suggest you take advantage of ElastiCache to reduce the number of DB hits.
I know from a caching perspective that StackOverflow was built using Redis.
Check out Which tools and technologies are used to build the Stack Exchange Network?.
Related
I'm currently facing a few issues which I need advice on.
I apologise in advance if the questions don't make much sense or if they have been answered before (I found somewhat relevant questions, but either didn't understand the answers or did not think they applied to my situation). Any guidance in this field or answers to the question would be extremely helpful.
Situation: We have a standalone app rolled out to customers, which uses AWS Userpools for user accounts.
Issue number 1, storing the AWS (and other) API keys:
I've read around and quickly realised the most secure location to store them is server side.
We have an FTP server set up currently used for auto updates which I assume can also be used for retrieving the API keys.
Issue with this is that we still need to store the information to access the server somewhere securely.
What would be the best approach for storing and accessing API keys on server side?
Once API keys have been retrieved can we store them in memory to not have to access server again?
Issue Number 2, feature flags:
Due to different pay levels we have implemented feature flags, these flags are retrieved from a database when connecting to the app online.
However if they need to get on the app whilst offline they need to be stored locally in a way where they can not be modified.
Is it safe enough to encrypt the data and store it in a file locally and decrypt it on app startup?
Issue Number 3, making sure the user is ok to use app if offline:
As we want the user to not be able to log in after a set amount of days in offline mode without reconnecting I imagine I should be going down the route of using the AWS Userpool Tokens. How would one safely store these tokens to persist through app closure and is there any risk of storing them locally?
I imagine encrypting the server access information and feature flags in files is a way to go, however then we need an encryption key in order to decrypt these files. Where would one store that?
Note: I'm more concerned about the API keys rather than the feature flags.
I am developing an application that will support several departments in our organization, and want to define what data is accessible by AD Groups a user is in.
My question is, is it more cost effective resource wise (bandwidth, time slices, etc) to use an IsUserInRole() call at each decision point or to load several Session[] variables at user login which are Boolean and use those throughout my code?
Thoughts?
I would avoid Sessions. They make scaling an application harder since you need a centralized store (a Database or Redis), while will be hit at every single request. It slows down the process since you have to wait for the request to complete before going on with the actual business logic.
The answer for this is using JWT tokens. They work very well for small amount of data (like a limited amount of roles, not hundreds of them). JWT tokens can safely be put inside a cookie so every browser request carry it to the server.
You may get more information about JWT tokens here: https://jwt.io/introduction/. This other StackOverflow question has a lot of information about JWT tokens: Using JWT to implement Authentication on Asp.net web API.
I hope it solves your issues. Good luck.
I've been trying to get my head around SSO in an enterprise environment and what solution best fits my companies problem.
We have several apps (mostly in .net but some in java) running on our domain.. a.mydomain.com, b.mydomain.com etc...
My problem lies in trying to figure out how to implement Single Sign On, because as far as i can see, the likes of OpenID and OpenAuth are used for facebook, twitter, linked in based SSO, ie consumer based SSO.
We want an internal SSO system setup but I cant find many enterprise examples of how to do this and what protocols/frameworks/servers to use.
Can anyone give me an idea how and if OpenID/OpenAuth should be used for this case, and what the benefits and disadvantages are?
also, would token based SSO be a good idea for this? considering all the apps wiill be on the same domain (SSL is setup).
Finally, what about cookie based SSO, is this a good idea?
Thanks
Neil
As you mentioned that all your apps are in the same domain and you are looking for an internal SSO solution I would recommend going for a cookie based SSO service.Simply because
It will be easier to implement. Just checking the cookies and giving the user access to an app.
no XML message exchange between your different apps (no need to design a schema)
You don't need to hire any Web service experts. (As long as your developers know how to handle cookies)
ultimately it will depend on your scalability requirements.
update:
Scalability:
In future you might expand you user-base across different geographic locations.
Your different applications might have different servers and the user database might become distributed.
In such cases you will have to maintain an identity repository to give authentication as a service.(This is what is done by the authentication frameworks that you mentioned)
Cookies:
Cookie handling is no rocket science. The browser automatically sends cookies to
your server in the HTTP request and you just have to read it.
Create the cookie wen user logs in. Set the domain property to your root domain so that
other sub-domains can access it.
Check for cookie when user tries to log into an app. If cookie is present that means the user has already logged in.
Don't forget to delete them when user logs out.
Active Directory Federation Services (http://msdn.microsoft.com/en-us/library/bb897402.aspx) is an enterprise solution. I would not recommend writing your own token issuer as there are lots of risks involved, security and performance.
I have a Asp.Net MVC4 website which can connect to multiple databases depending on the user's login credentials. In order to get the database access list for the user, I have to perform a few complex joins when they login. To avoid having to do this more than once, I am currently encrypting and storing the database ID in a cookie. I now realize that this may not be a good idea and even strong encryption may be broken. In addition, the encrypted cookie is transferred around on every request increasing traffic. I am now thinking about using the HttpContext.Current.Cache to store the data instead. Can anyone comment on whether this is a good idea. I would also be interested in knowing if there are better options out there. My website is not deployed on a server farm right now but what would be the implications if I were to use a cache and a server farm in future?
Based on your requirements (i.e. keep a hold of sensitive user specific info across a session), the correct place is for this is the SessionState. AFAIK sessions states can be shared across multiple web servers so if you did use a server farm you wouldn't need to change anything.
Session is right container for user sensitive data. Or you can store it in database and get it there by some identifier that is stored in session(it is useful if you store large amount of data).
I know this question as been asked countless times, but believe me I've searched Google for hours and got nothing. Whatever is out there, it's for MVC, which I'm not using.
My requirement is simple. I do not want to use the default authentication provided in asp.net. I would store the username/password/role in my custom SQL Server table. I'll provide 2 inputs for username/password and a button to validate. On validation, he is allowed access to the admin areas. This will only be used by admin guys at my subdomain "admin.*.com". They will use this page to add content to the website on daily basis.
How do I implement it. A tutorial link would suffice.
Is it safe for Production? I don't want some newbie hacker getting in to my site and mess it up. If not safe, what else option do I have.
Thanks,
Dev
As per our comments, given your reluctance to implement an ASP.Net Membership provider (and it is worth the time to investigate - you may not feel that it is right now, but it can be handy. I felt the same way at first, but the cost of maintaining your own code and infrastructure soon proves to be false economy) you have at least two other choices:
1) Straightforward Forms Authentication
Put all of your admin pages under a single folder, for example, /Admin, then use Forms Authentication to protect access to this folder. Only users defined in the database or Web.Config will have access to these pages. This is less flexible than ASP.Net membership, but may give you most of what you want. In terms of security, this will be as secure as your website is, is well tested, and is well documented.
2) Use Facebook OAuth
You mentioned that your use has access to Facebook. You could use Facebook to do the authentication for you. Although you wont be able to grab the username and password, you can get a token back, that you can then validate against a known permission set. This is a lot more work than 1) though and will tie you to potential future changes in the Facebook API. However, it also benefits from being well tested, and secure, but you have little to no control over the actual user information.
As an aside, please also consider being nicer to Google!
You can create your own custom membership provider which has the features you are looking for.asp.net membership provider
Its best to use the tried and tested method for security purposes. Remember you can customise any providers including role providers or even create your own unique providers.
Here is an example how to LDAP authentication using ASP.NET 1.1. The logic may still be applicable or can be adapted to later versions of ASP.NET, although I have not tested it.
Using the built-in membership providers, or implementing your own, is no guarantee that a hacker can't get access to your system. Things you'll have to consider:
encrypting data between client and server
don't store passwords in the database, not even encrypted. Hash each password its own salt, if you can.
enforce strong password entropy.
make sure session and authorization cookies are marked HttpOnly and Secure
for admin passwords, have a policy to change them frequently (like once a month)
provide means to notify administrators when someone signs in to their accounts
temporarily lock out ip address who exceeds number of requests per second and failed to authenticate
temporarily lock out users when they enter their password more then x (e.g. 10) number of times in an y number of minutes (e.g. 10).
These are just a handful of things to look for. You'll also have to concern yourself with session highjacking, javascript attacks and so forth.
Its not a trivial matter.
Writing a custom authentication handler is very dangerous. There are many ways to get it wrong and leave your website vulnerable to attack.
I also understand your complaint that Forms Authentication is extremely complicated. I was faced at a similar cross roads and decided to build my own authentication system called FSCAuth. It's BSD licensed. It's designed to be super simple and to allow for just about any database format you can image. All that must be done to set it up is implement a small 4 function interface into your database and populate a few configuration fields.