Can't we just store in the session if the user is logged in or not and get rid of the .ASPXAUTH?
ASP.Net_SessionId is a cookie which is used to identify the users session on the server. The session being an area on the server which can be used to store data in between http requests.
For example, the controller action may perform:
Session["FirstName"] = model.FirstName;
Then, in a subsequent action the first name can be retrieved from the session:
var firstName = Session["FirstName"];
The ASP.Net_SessionId identifies the session for that users request. A different user will submit a different cookie and thus Session["FirstName"] will hold a different value for that different user.
ASPXAUTH is a cookie to identify if the user is authenticated (that is, has their identity been verified). For example, a controller action may determine if the user has provided the correct login credentials and if so issue a authentication cookie using:
FormsAuthentication.SetAuthCookie(username, false);
Then later you can check if the user is authorised to perform an action by using the [Authorize] attribute which checks for the presence of the ASPXAUTH cookie.
So in summary, the cookies are there for 2 different purposes. One to determine the users session state and one to determine if the user is authenticated.
To complete the answer to your question, yes, you could get rid of the ASPXAUTH cookie and just use session to identify the user (I have seen this done in older classic asp applications) but I wouldn't recommend it. It is much better to have a cleaner separation of concerns and use the appropriate method where necessary. The session and authentication will have their own time-out values set. By using the session for authentication you will only have the single time-out. I'm not sure though if there are any security implications in just using session for authentication, but still I would keep them separate.
.NET issues an entirely different cookie, named ASP.NET_SessionId, to track session state.
The ASPXAUTH cookie is used to determine if a user is authenticated.
So these are 2 different concept i.e. Session State Management and Authentication Management using Form Authentication.
If you use Session to Authenticate and forget Form Authentication you will get rid of .ASPXAUTH
Both are required , using either resulting in the following vulnerability:
*ASP.NET_SessionId Alone: Session Fixation
*Forms Authentication Cookie Alone: Can’t Terminate Authentication Token on the Server
Also, you need to ensure they coupled together properly.Otherwise, the configuration also pose risk:
*Loosely Coupled ASP.NET_SessionID and Forms Authentication Cookies: Still Vulnerable
ref:
http://blog.securityps.com/2013/06/session-fixation-forms-authentication.html
Session state and authentication have nothing to do with each other. You can use one without the other.
Related
We have a log-in form in ASP.Net Webforms. and when user logs in we save the user id to session state.
Session["CurrentUserId"] = user.Id;
So this is how we know a user is logged in.
if(Session["CurrentUserId"] == null) Redirect("Login.aspx");
This is all we use Session for. I am storing session in DynamoDB because we have many load balanced servers. But sometimes DynamoDB gets overloaded or gives errors. So I trying to get rid of session state to avoid these errors and to simplify a login process.
So what alternatives are there? How do modern websites log people in and remember they are logged in, and timeout after x minutes?
Is there a way to use a secure cookie to just do it? And how would you expire it if user doesnt do anything for 20 minutes? It has to work over a collection of web servers.
Storing user ID in session is not necessarily bad but has to be combined with other things in order to secure the site against things like session fixation attack and CSRF (also known as "session riding"). It is also problematic in a web farm if you are using in-proc session state.
In ASP.NET web forms, the standard way to authenticate is to use forms authentication, which places an encrypted cookie ("authentication ticket") on the browser. You may also want to put the user ID somewhere in session and compare it to the authentication ticket in order to ensure they match.
if you using the standard FBA login providers?
You can get user logon ID with this:
Membership.GetUser.ProviderUserKey
And you can get user email with this:
Membership.GetUser.Email
So, the user logon id can be fetched with above.
As for session() being a bottle neck?
Well, it not all that bad - you not "updating" the session() value by doing this, so it certainly does not have to be written back each time (for a post) and also it means that a lock on session() during post backs etc. should not occur.
I would however consider one of the above two approaches, since then session() re-sets or anything else would not matter to get the user ID, or email.
As noted, this much depends on what security and authentication provider you are using here.
We are using Gigya to authenticate the user which will provide us with user Id and email. Then we pass the user detail to our CRM Web Service which will return the user data from CRM.
We then need to create a session for the user so that we can identify whether the user is logged in or not. If not logged in then redirect to Gigya for login/register etc.
Now, given that we are not using any ASP.NET Membership or similar, I'm thinking how we are going to secure the member pages. One way I can think of is store the user detail in session. Then check if user detail exists in session, if doesn't exist prompt for login.
I'm also thinking whether:
I can use FormsAuthentication.SetAuthCookie or similar to create a asp.net session
Or is there better way to achieve this.
Also, if I use FormsAuthentication.Logout will it clear all my session and cookies even though I'm not using asp.net membership provider?
Goal:
To be able to create a session for the user
Able to authorize user based on user role which we get from CRM.
Able to logout the user on Lout button click.
First, and this is very very very important from a security perspective.
Authentication != Session.
They are different concepts. Second,
NEVER USE SESSION for AUTHENTICATION
see first rule. FormsAuthentication has nothing. Zero. Zilch. Nada. To do with session management. Nor does it have anything to do with Membership or credential verification. All it does is store a cookie that ASP.NET can decode to verify that the user is authenticated or nor. This cookie is set by your application when it has validated the users credentials.
FormsAuthentication.Logout() does not clear sessions, because as I already said, they have nothing to do with each other. You have to clear the session by calling Session.Abandon().
Session is about storing data for a user, and is not secure. Session is volatile, and IIS can discard it whenever it feels like, for any reason, at any time. You cannot depend on Session to be there from request to the next.
Authentication is encrypted, and strictly about proving the user has been authenticated.
Authentication can transcend sessions. It can be good for hours, weeks, months... Your session is only good for the time you are currently there (if IIS doesn't kill it earlier).
Consider the case of forms authentication with persistent cookies.
If the same user logged in using two different browsers or two different machines, when user logs out from one of the browser/machine, wouldn't still he be able to login from the other browser/machine?
Usually, how do web applications handle this case?
I have to agree with Srinivas for the most part. Here is my take on the subject
On Login create an HTTP Only cookie with a guid generated at login this will be your browser/computer key. Closing browser will remove cookie
Get user id
Persist in the pair in user table ex: user:a, key:12345
On subsequent requests authentication algorithm after user has been authenticated
Get the last used key in the db with current user id
Check that the cookie is present, if not then completely unauthenticate
Check that the cookie value is the same as that in the database, if not then completely unauthenticate
With this method any subsequent login will cause a required reauthentication & invalidate any other authentications. In effect forcing the user to use only 1 browser/computer
I usually do it this way : I have a session column in my user table(in database) When the user logs in I store the value Y in it.I change it to N when he logs out.Every time the user tries to log in, I check the value in the corresponding session column and if it is Y I tell the user that he is already logged in and if it is N then I allow the user to log in. But we have to be careful and set the value to N when the user logs out or closes the browser.
Forms Authentication with cookies (regardless of whether they are persistent or not) is browser session based (persistent cookie would of course work across multiple sessions of same browser (on same user account on same machine). So two browser sessions (or two different browsers or browser on two machines etc) would be treated as different scope as far forms authentication is concerned.
So user can make multiple login from different browser sessions and logout in one will not affect other. Its is up to web application whether to allow multiple concurrent logins for same user or not. For example, online banking sites would restrict to only one user session - so if user logs in from different session then earlier session is invalidated (i.e. user is logged out). One has to write custom implementation in ASP.NET to do so - typical implementation would make every user session entry into database (typically required for audit purposes anyway) - so whenever new entry is added, a check is made to see if there is any active session for same user and if yes then that session is marked inactive. Every request would check if current user session is active or not, if not then it would flag such message to user.
I am building a multi tenant MVC4 web application. I distinguish the tenant based on the url alias (customername.webapp.net). I have a database that stores the customer id which I can lookup using the customername.
Obviously I need this customer identification during the entire session that a user from that customer is using my webapp.
Is it acceptable to store this unique identifier in the session? Or are there better design choices for this kind of "session data"?
I'd rather store this information inside the UserData portion of the forms authentication cookie (if you are using Forms Authenticatoin) or simply add it as a claim if you are using claims based authentication. When the user logs-in you would extract the tenant name from the current request, query your database in order to obtain the tenant id and then persist this id. If you store the id in the UserData portion of the Forms Authentication cookie you could write a custom [Authorize] attribute which will read the FormsAuthenticationTicket, decrypt it, get the tenant id from the UserData portion and then build a custom principal. This way you will have it available everywhere in your application. If you use claims based authentication, you would simply add it as a new claim.
I wouldn't use Session at all inside my application.
Please don't be misguided by the answer. It is dangerous to use cookie.
Session in this case would be the valid option, not cookies. If you store your tenantId inside your cookie, and your application establishes database connection based on your cookie, then after you login as a user, you can tamper and change the cookie and now your application will make connection to another database thereby compromising security. Even if your cookie is encrypted, it's not 100% reliable.
Session in this case would be the reliable server information that keeps track of which tenant database should be connected to. Although session can be a performance drop compared to cookie, in this case you have no other good options. You are designing a multitenancy application and that's just something you have to sacrifice.
Yes, you may still able to use cookie if you REALLY want to. You just have to keep checking if the user is connected to the right database somehow, which to me is more of a performance drop than using session.
Don't hate session just because alot of people abuse it or hate it. You just have to use it in the right manner.
Bottom line is, if you are using any info for security purposes, don't use cookie.
I am developing my login for my new homepage.
Now I found out, that I must save something like the userID (or another value that i can recognize my user) in the session variable of the browser.
At the moment I use INT for the userID.
So isn't it unsafe to put the userID in the session?
E.g. when I edit my session variable manual from userID 111 to userID 112, than I am logged in as a complete other user?!
Yes, it is unsafe to rely only on user ID.
You may wish to add a unique authentication token generated and remembered by the server. Also a very simple solution, but it will stop manipulating the user ID since the correct value for authentication token for the other user cannot be guessed.
You also need to submit both user ID and the corresponding authentication token at each request to be jointly validated on the server side, prior to performing the requested operation.
P.S. The above applies if you store this information in cookies which are accessible on the client side and can be manipulated. The viewstate (serialized in pages) can also be manipulated. The session collection is a server-side variable that is not available on the client so it cannot be manipulated. In this later case your user ID should be safe.
I would recommend you to implement the dual system: store the user ID and the token both in cookies and in the session and use the same validation logic (for simplicity). Should cookies be disabled you automatically fallback to using the session without changing your code.
The session variable is not stored in the browser, it is stored on the web server. (Typically anyway.)
A token indicating which session variable to use, is stored in the browser.
So storing the userid in the session variable is fine, as the user has no access to this directly.
If the user were to change the session token, to another one, that would be a problem, but they'd need to know the other token first. (I'm not sure how to do that myself.).
(You can further diminish this by using encryption, or other identifies like IPAddresses etc, it's really a case of how secure do you need your website to be?).
Also, if your site needs the user to log in, it's advisable to use https/SSL.
As Bravax says, the user does not have access to the Session variables (Cookies they do have access to).
If you are worried at all I would use a GUID instead as they are not sequential and nearly impossible to guess.
Also, have you looked at the built in stuff in .Net for authentication? Look at FormsAuthentication.
HTH,
Arry