I am developing session management for our Web-server. Below are steps I am following.
Very first time user comes to our server, We authenticate him based on username:password
provided and generate/set secure-cookie.
For subsequent request web-client will send same cookies back to us and we will validate
it.
If cookie is valid then we serve the response. If cookie is invalid then we check
if authorization credentials are present and try to authenticate user and again
generate/set secure-cookie
If cookie is not valid and no authorization credentials are present then send 401.
With cookie we are also setting expiry time. This mainly for inactivity timeout.
I want to know if I should regenerate cookie for subsequent request or not.
what will be a good design to generate or not to generate.
If we don't generate then how we can keep user logged in ?
You need to provide sliding expiration. For example you define an idle timeout of 5 min, then when the user performs a request in the last two minutes, you deploy the same cookie with a extended expiration.
ASP.NET uses this technique.
Related
How can I sign in with a different account per tab in asp.net mvc 5 and Identity?
Is there a configuration that doesn't use cookies?
This is my configuration code:
' Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(New CookieAuthenticationOptions() With {.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, .LoginPath = New PathString("/Account/Login") _
})
' Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie)
This is not possible. The web is stateless: each request is a unique snowflake, unaffected by any other request made before or after. However, since logically some sort of state needs to exist for things like authentication, sessions were created to basically fake a sense of state.
To work, sessions have a server-side and client-side component. On the server, some persistence layer is employed to store user-related data tied to a token that uniquely identifies the particular session. On the client, a cookie is set with that token. When the client makes another request, all the cookies that belong to the particular domain in play are sent along with the request back to the server, which includes the cookie with the session token if one exists. Once the server sees this cookie in the request, it uses the token to look up the session from the persistence layer and restore the state the user had during the previous request.
The point is that this process is dumb. The client blindly sends any cookies the server sets back to the server with each request. And, if the server gets a cookie with a session token it recognizes, it blindly restores the state. There's no consideration for how many tabs are in play or even what the content of the cookie is (the client doesn't know and doesn't care that the cookie is being used to manage a session, authentication, etc.).
Long and short, there's nothing you can do to force a session per tab or window. On the client-side, you can open a different browser (which would not have the cookie holding the session token) or use something like Chrome's incognito mode (which creates a sandboxed browsing experience without any previously set cookies). However, those are choices the user makes, not the website.
Is there a way to remove the authentication cookie, or sign a user out once they are removed from the asp.net membership database? By default if a user is removed from the database, the user can still browse the website since they still have a valid authentication cookie.
I've tried different things within global.asax but nothing seems to work. Is something like this even possible?
See here: FormsAuthentication.SignOut Method. Although this refers to users not being logged out server side, a similar approach can be used for managing deleted users.
Calling the SignOut method only removes the forms authentication cookie. The Web server does not store valid and expired authentication tickets for later comparison. This makes your site vulnerable to a replay attack if a malicious user obtains a valid forms authentication cookie. To improve security when using a forms authentication cookie, you should do the following:
Use absolute expiration for forms authentication cookies by setting the SlidingExpiration property to false. This limits the window in which a hijacked cookie can be replayed.
Only issue and accept authentication cookies over Secure Sockets Layer (SSL), by setting the RequireSSL property to true and by running the entire Web site under SSL. Setting the RequireSSL property to true ensures that ASP.NET will never send an authentication cookie to the browser over a non-SSL connection; however, the client might not honor the secure setting on the cookie. This means the client might send the forms authentication cookie over a non-SSL connection, thus leaving it vulnerable to hijack. You can prevent a client from sending the forms authentication cookie in the clear by running the entire Web site under SSL.
Use persistent storage on the server to record when a user logs out of the Web site, and then use an application event such as PostAuthenticateRequest event to determine whether the current user was authenticated with forms authentication. If the user was authenticated with forms authentication, and if the information in persistent storage indicates the user is logged out, immediately clear the authentication cookie and redirect the browser back to the login page. After a successful login, update storage to reflect that the user is logged in. When you use this method, your application must track the logged-in status of the user, and must force idle users to log out.
The third option is the most secure but requires the most effort. IMO, the first two do not resolve the issue adequately.
It is also possible to store custom information in the Forms Authentication Ticket. You could store the last explicit logout time in this ticket, and check it against your server side database record. Please note that if this record is at user level instead of session, then all logins under that account would be logged out at the same time.
In your case, if you are deleting server side user and session records, as the record does not exist you will be able to also fail the authentication request.
I'd advise also storing and checking the last date/time the password was changed - that way if a user updates their password then all existing sessions are logged out.
How can you suspend access to a user session after a specified interval of inactivity when using Windows Integrated Security for an ASP.NET MVC Website?
When using Kerberos for authentication Internet Explorer (IE) will continue sending the same credentials for each subsequent request to the server until one of two things happens:
a) The user closes their browser.
b) The server refuses the credentials with a 401 status code.
This behavior is KB 264921.
If we want to simulate a session than we have to implement the following steps:
Create a sliding expiration cookie for the duration of the session.
Check for that cookie for every request: begin_request or global filters. If the cookie is missing return a 401 status code for that specific request.
Next request will trigger the authentication prompt.
I was hoping someone else having a better ideea, this one feels kind of hacky.
In asp.net, I am able to login using forms authentication as usual, copy our auth cookie value, log out, add the cookie artificially to the client using the 'Edit This Cookie' addon for Chrome, refresh the (anonymous) landing page and hey presto i'm logged in again. This seems to be a vulnerability - is there any way of fixing it using the the standard forms auth or will I have to do something like use a custom Authorize attribute which overrides the existing one in asp.net mvc?
I don't think this is a bug per se. The following happens during forms authentication
You provide a username/password to the server
Server validates username/password
If valid, the server then sends an encrypted authentication ticket (cookie) to the client with the expiration time (set in the web.config forms authentication section) and username (all encrypted)
On each request that requires authorization, the cookie is decrypted on the server, expiration time is checked and username is used to see if authorized (or getting that role for the requested resource).
When you logout, the expiration time on the cookie is set in the past, therefore, it is not longer a valid cookie
Now, as to why you are seeing what you are seeing... You are copying the cookie before you logout. Thus your copied cookie never registers the logout (moved expiration time). When you reattach, you still have a valid auth cookie. Now, if your forms authentication timeout is set to...let's say 20 minutes...this method would fail if you copy the cookie and wait 21 minutes as by that time, it has expired.
Cookies are always vulerable and we can't do much about that. What we can do is prevent someone from stealing the cookies.
Regarding ASP.NET MVC it does a good job to avoid stealing cookies. Some of the main things it does by default as part of security are:
Encode the strings that are rendered to the view (if you are using Razor don't know about others) to prevent from XSS attacks.
Request validation (stop potentially dangerous data ever reaching the
application).
Preventing GET access for JSON data.
Preventing CSRF Using the Antiforgery Helpers
Regarding cookies Microsoft provides HttpOnly feature and this helps to hide the cookies from javascript. The Forms authentication that you are talking about is a HttpOnly cookie means someone can't steal that through JavaScript and it's more safe.
You can do that with any cookie/s. You can inspect/copy all the cookies from any given domain, and spoof if you want. You can do that to yourself (only) because its your PC (or user logged in to PC). Obviously if you're on a shared PC, that is a problem (across all your info).
The act of "copying your cookie" is in fact one way malware attempts to steal/hijack your identity (or current session on some web site). That said, unless you have some malware, you can't just "copy cookies" of someone else.
Assuming logout is done, you can ask users to close their browsers so the expired cookie is removed from the (file) system.
What happens after authenticating using openid? In a simple case, the user-agent is redirected to OpenID provider(OP). After optionally login to the OP, the user-agent again returns back to consumer page which is mentioned in the 'openid.return_to'. Now the consumer also verified and sent back a '200 ok' response.
Now my question is what the user-agent should provide for the subsequent access to the consumer page. When returning 200, a cookie will be returned along with it? If so, what will be the content of that cookie? and every time the browser attach the cookie to access any page on the consumer domain?
What happens if the cookie is stolen? Can someone impersonate me by using the cookie?
As far as I know there is no cookies. At least not from the provider. OpenID providers don't actually manage you login sessions. They just tell you how actually singed in. You then associate that with a user in for example you database and manage your sessions as you see fit.