Silverlight 4 raise event on forms authentication cookie expiration - silverlight-4.0

I am stumped on how to fire an event in silverlight when a forms authentication cookie expires. I would like to redirect the application to a login screen immediately. I understand I can wait until a web service call fails but I think redirecting the user to login after inputing data is poor customer experience.

This cookie has a default timeout of 30 minutes. That means that if there is no communication with the server for longer than 30 minutes, then the cookie will expire and the user will be logged out. The actual implementation of how the expiry works is a little more complicated, but this is the simple version (you can find the more complicated behavior described here: http://support.microsoft.com/kb/910439). You can increase or decrease this value if required (in the web.config file), but it’s not recommended to make it too big. The longer the lifetime of the cookie, the more chance someone would have to steal it and impersonate the user. The short lifespan of the cookie is essentially a security measure, and should only be changed after careful consideration.
From Pro Business Applications With Silverlight 4, Page 250
I guess you could make a timer in the MainPage and just automatically redirect to the login if the timer wasn't updated for 30 minutes. I can't find the quote right now but I think I remember he also said that there is no real way of telling when the cookie expired.

Related

Recommended simple access token expire handling for app

I have a set of APIs purely for my own app, so I just have a simple API to create access token, when user provided the email and password
/api/access_token (return access_token when email and password matched)
The access_token was saved and matched against in the database sessions table with the expiry field, for now, the expiry is one week, so user need to re-login after one week.
So far it worked fine, but if I want to have the remember me functions as those Facebook / Twitter app, which mean user don't need to re-login so often, which I assume they are using something like the OAuth refresh access tokens approach.
Since I am not using those OAuth stuffs, given my current design and setup, what would be the simplest and secure way to achieve the same functionalities?
You have a few options to choose from, I'll try provide an overview. There is a significant difference depending on whether the client is a browser or a mobile app.
First, for browsers, plain old session tokens are generally more secure than JWT or other structured tokens. If your requirements don't force you to store stuff on or flow stuff through the client, then don't.
The most secure option for a browser client (single page javascript app or plain old rendered app) is the following:
When the user hits the login endpoint with their username and password, the endpoint creates a random session id, and stores it in a database.
The server sends back the session token as a httpOnly cookie, thus it protects it from potential XSS.
The client then automatically includes the session token in all subsequent requests.
Additional data can be stored server-side for the session.
This above is basically plain old stateful session management. The length of such a session should be limited, but if your requirements and threat model allows, you can make this a very long session, like months even if you want, but be aware of the associated risk. These tokens can be inspected in the browser and stolen from a user if not else then by physical access to the client, so a very long expiry has its risks.
Note that mobile apps can pretty much just do the same. The difference is that mobile apps do have a way to store secrets more securely on current mobile platforms. As the storage is protected by user login, and also segregated by app, a session id stored correctly in a mobile app has a lot less chance to be compromised, meaning a longer expiry presents lower risk than in case of a plain browser.
You can also implement a refresh token. However, the point in refresh tokens is that you want to store them in a different way than the other token. If they are stored the same way, a refresh token provides very little benefit (sure, it won't be sent with every request, but that's not where it will get compromised anyway, TLS / HTTPS is secure for transport). In case of OAuth / OpenID, the authentication server can for example set the refresh token on its own origin (like login.example.com), and then forward the user to the app with an authorization code for example, which can be exchanged by the application (service provider) for an access token, that is set for the application domain (like app.example.com). This way, the two tokens have different access models, a compromised app will not leak the refresh token, even if the current access token is leaked, and the access token can be refreshed relatively seamlessly.
If you don't have a separate login endpoint, all this doesn't make a lot of sense, except in one very specific case. Thinking about browser clients, you can set a refresh token in a httpOnly cookie, so it's protected from XSS, and you can store an access token in something like localStorage. However, why would you do this? Pretty much the only reason you would do this is if you need to send the access token to some other origin, which is the whole point in OAuth and OpenID.
You could also argue that statelessness is a benefit of such tokens. In reality, the vast majority of services don't actually benefit from statelessness, but it makes some features technically impossible (like for example forcing logout, as in terminating existing user sessions - for that, you would have to store and check revoked tokens, which is not stateless at all).
Ok so to provide "remember me" as in auto-login, you basically have two options. You can either just make your sessions very long (like months, years, forever), which is more ok for mobile apps as they can store the token more securely than a browser, or you can implement some kind of a refresh mechanism. As discussed above, this only makes sense if the refresh token is stored and accessed differently than the session token.
In case of a browser app with a single origin (no auth/login service), this is not really possible, there is no real separation, and a refresh token doesn't make a lot of sense. If you want an auth service, you should be looking into OpenID Connect (OIDC).
For a mobile app, what you could do is store a refresh token in secure storage, and use access tokens from the localStorage of something like a webview, but unless there are very specific requirements, this would likely not be worth the complexity, as you could just store a longer lived session token in the secure storage.
As for remember me, you can just implement it in a way that users that choose to be remembered will have a sessino token with a longer expiry - as you already store expiry for each token in your database, everything is already set up for that, and in many usecases this is fine. There is some additional risk for users that choose this, but there is also some additional benefit in terms of convenience - it's always a compromise.
What you can consider doing to make such very long sessions more secure is check and store some kind of a device fingerprint (there are Javascript libs for this). If you have a very long lived session, but only valid for a specific fingerprint (ie. it only works from the same device), that mitigates the risk somewhat. However, almost everything that is used for a device fingerprint can be spoofed by an attacker, but it still makes it significantly harder for an attacker to steal a session, and you can have approrpiate monitoring in place for attempts. There will be UX considerations too, like the fingerprint might change with browser/app updates and so on, but it's still worth it sometimes.
Another new-ish feature you could consider is WebAuthn and Passkey, for passwordless authentication. These basically provide device authentication, a key will be seamlessly generated for the user on the specific device, and that will be used for logging in. UX is now getting better, but there are still challenges. The way device authentication translates into user authentication is that the key is associated with the user session (the user "unlocks" the keystore, ie. decrypts the stored keys upon login, with their login credentials). This can also provide "remember me" (seamless auto-login), but in my experience the technology is not fully ready yet, though it's getting there.
While I fully agree with the comments above, I would like to create a clear solution in the minds of other readers by giving a clear and directly understandable concrete answer to your problem.
Let's take an example for JWT;
RefreshToken is the structure that will be activated when the AccessToken expires and will complete the Authentication phase without the need for login. The logic is as follows: AccessToken has a very short lifespan compared to RefreshToken. This time is up to you. The purpose is this: AccessToken is destroyed in short time intervals so that it does not fall into the hands of anyone. However, for this reason, the need to login to the system again arises. To make it easier to login again; When you take the previous AccessToken, you will take another token (RefreshToken) that can be used for a longer period of time and keep it in your pocket. The part I call your pocket depends on the technology you use. For example, you can also keep it in the browser. Keeping it in a browser is not an ideal method (It would be DB, file, cache what you use), because it can create a security vulnerability when someone has access for browsers. So where to keep it depends on the situation and you decide, but; RefreshToken will be activated when AccessToken expires on your client Login functionality.
It has become customary to set a default period of 100 days for RefreshToken. however, this time is up to you, depending on your application business preference.
I found a very clear example when I googled, you can check it below.
https://www.c-sharpcorner.com/article/jwt-authentication-with-refresh-tokens-in-net-6-0/
You can use the same functionality on your serverside code for all your clients (mobile or web not important)

How to block user with immediate effect in auth0

I tried auth0 and I face a problem where I can't block or force logout a user.
After i blocked a user from auth0 console, The user who was logged in could still access the routes.
I used express-openid-connect middleware and requiresAuth()
I suppose this is a common problem with JWT based service ? and should I implement a statefull session to manage user for these kind of use cases ?
In JWT based services it’s common practice to make the access token lifetime a short one, e.g. 10-15 minutes. That way user can still access the api inside a short window but soon the token needs to be refreshed. And when token refresh takes place the authentication service gets called and can reject granting a new token.
So you can make sure your access token lifetime is short enough and that should be enough to satisfy the security requirements.
It’s of course technically possible that you implement stateful session to check user info on each request but you should not call Auth0 api in this case cause you are going to hit their rate limiter and it slows down your api requests. Some sort of sync to your server side fast read database/cache would be needed.

IdentityServer4 - How to log in user following password reset if existing auth cookie exists?

I'm attempting to extend my Identity Server 4 implementation and provide an in house password reset feature. I've completed the entire password reset process however I'm running into a situation upon redirecting the user back to the client application that's causing me grief.
If there is a valid existing authentication cookie, for instance if a previous user doesn't initiate a proper log out, when I redirect the current user to the client application, the middle ware uses the existing cookie to build the principal which inevitable ends up with the current user being treated as the previous user, which makes sense.
In vain I attempted to make a call to sign in the current user post password reset in Identity Server via await HttpContext.Authentication.SignInAsync(...) as shown during login on their samples here with no change in results.
It seems as I'm missing something fundamental in how to properly reproduce the sign in process from within my password reset process.
Is there any way from Identity Server that I can effectively sign in the current user post password reset and force the client application to invalidate/ignore the existing authentication cookie?
Update: After thinking about this over the weekend, I guess this broaches a much broader subject in that how far does one go in ensuring the invalidation of existing auth cookies? The fact is that because of the way cookie authentication works, as long as that cookie remains valid we are under the assumption that we are is still receiving requests from the original physical person.
One might argue that this is a good case for reducing the expiration time of the cookie, but that's a slippery slope because on one hand if the expiration is too short, usability can be affected making for a less enjoyable experience and unhappy users. Make the expiration too long and that window where a valid auth cookie is sitting on the browser idle with no meat and bones behind it grows, and all it takes is someone else to browse to the site to proceed unhindered and authenticated as someone else. This would be most evident in a situation with shared computers where many people need to access the same app.
I suppose a secondary question would be to what extent is the onus on the user to initiate a proper logout process, and to what lengths should I go to to ensure any existing auth cookies are invalidated?
After a few conversations with co workers, the consensus was that it is the responsibility of the user to ensure they are properly logged out in any public/computer sharing situations and that we could not guarantee without a reasonable doubt any previously existing authentication cookies are cleaned up without greatly affecting user experience and basic site functionality.
For due diligence we however will provide some manner of attempting to clean up any existing authentication cookies by doing a simple check and redirect on the default route of the client application. This solution has nothing to do with identity server, and is not fool proof, but in conjunction with tuning the session expiration times should prove effective for daily users.
[AllowAnonymous, Route("")]
public async Task<IActionResult> Index()
{
if (User.Identity.IsAuthenticated)
{
await HttpContext.Authentication.SignOutAsync(...);
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
}
return RedirectToAction(nameof(Welcome));
}
[Authorize]
public IActionResult Welcome()
{
return View();
}

Login timeouts: in what cases are do you use them?

I'm wondering when login timeouts are being used, specifically when using same session (same browser session). On a number of sites I have completed recently I have added 60 minute timeouts and they seem to be causing problems, such as users are not able to fill out larger forms (like a resume submission--people don't think of copying their resume from another program or saving part way through). On one site, I have implemented a div/popup forcing the user to enter their password to continue in the current session, without having to login again.
But on other sites, such as Facebook, it seems you are never logged out as long as you are using the same browser window, even without "remembering" your password.
The main reason I usually use timeouts is to ensure the data is secure, such that another party can't sit down at the computer a few hours later and use the system as the original user.
I'm wondering how you decide when a site should time out users because of inactivity?
I'm thinking the answer would be language agnostic.
IMO, they're valid when:
security is critical (ie. banking)
the likelihood of seat-swapping is
high (ie. public terminals)
Regardless, there may be instances like your resume system, where you want people on public terminals to be able to carry out an act that may leave them inactive for longer than your desired or necessary timeout.
I suppose you just have to handle that in a smart fashion - either figure out a way they can get the data in quicker (which would be ace, spending an hour filling out a form is not fun - can they just upload a file?), or ensuring they can continue without any data loss after being prompted to log in again.
Even though 60 minutes seems like a long time to fill out a single form (perhaps the forms should be divided into multiple pages?), you can probably use SlidingExpiration to solve the problem where your users get logged out even though the browser session is alive.
I think the timeout for an auth cookie is a Security level decision. If your site is SSL secured, you would probably have minimal timeout values (user session would expire within a matter of minutes). On the other hand, for sites with non-critical security, you could set a medium timeout value.
When I sign on to online banking, for example, it asks me whether or not I am using a "public terminal": and if I say yes then it enforces stricter security, or if no then laxer.

Best way to deal with session timeout in web apps?

I am currently building an internal web application used in a factory/warehouse type location. The users will be sharing a single PC between several people, so we need to have a fairly short session timeout to stop people wandering off and leaving the application logged in where someone else can come to the PC and do something under the previous user's username.
The problem with this is a session can timeout while a user is currently entering information into a form, especially if they take a long time.
How would you deal with this in a user friendly manner?
Keep the server informed about the fact that the user is actively entering information.
For instance send a message to the server if the user presses the TAB key or clicks with a mouse on a field.
The final solution is up to you.
Use AJAX to regularly stash the contents of the partially filled-out form so they have not lost their work if they get booted by the system. Heck, once you're doing that, use AJAX to keep their session from timing out if they spend the time typing.
The best advice would probably be to ask the users to close the browser window once they're done. With the use of session-cookies, the session will automatically end when the browser is closed or otherwise on a 30 minute timeout (can be changed afaik).
Since there by default is no interaction between the browser and the server once a page is loaded, you would have to have a javascript contact the server in the background on forms-pages to refresh the session, but it seems a bit too much trouble for such a minor problem.
If the session timeout is so short that the user doesn't have the time to fill in a form, I would put an AJAX script that makes a http request to the server, every few minutes, to keep the session alive. I would do that only on pages that the user has to fill in something or has already started filling something.
Another solution would be to use a session timeout reminder script that popups a dialog to remind the user that the session is about to time out. The popup should display a "Logout" and a "Continue using application" that makes a ajax request to update the session time out.
Maybe that a keep-alive javascript process could be helpfull in this case. If the script capture some key triggers, it send a "I'm still typing" message to the server to keep the session alive.
have you considered breaking the form into smaller chunks?
Monitor the timeout and post a pop-up to notify the user that their current session will expire and present "OK" or "Cancel" buttons. OK to keep the session going (i.e. reset the counter to another 5 minutes or 10 minutes - whatever you need) -or- Cancel to allow the session to continue to countdown to zero and thus, ending.
That's one of lots of ways to handle it.
Using a JavaScript "thread" to keep the session open is, to me, a bad idea.
It's against the idea of session timeout which exists to free some resources if there's no user in front of the application.
I think you should adjust the session timeout with the more accurate time, in order to fill the form in an "typical normal use".
You may also be proactive by :
having a JavaScript alert displaying a non-intrusive warning (not a popup) to the user before the timeout expire, which say that the session will expire soon (and give an link to send an ajax request to reset the timeout and remove that warning - that will avoid the user to lost the form he is currently typing),
and also have a second JavaScript "thread", which, if the session has expired, redirect to the login page with a message saying that the session has now expired.
It think that's the best because it avoid the user to fill a complicated form for nothing, and handle the case when the user has gone away.
As an alternative for the technical solutions, you could make your application in such a way that everytime a particular job is done, for example filling in a form, you ask the user if he wants to continue doing another job or if he's done. Yould could have a startscreen with menu options and if the user chooses an option he first has to enter his credentials.
Or put a password field on the form. Depends on how many forms they have to fill in a session.
When the user posts the form and their session has timed out, you should make sure you save the form values somewhere and then ask the user to login again. Once they have re-authenticated you they can then re-submit the form (as none of their data will have been lost).
I had developed something requiring very long session. The user logged in on a page when he sit on the machine and after doing his work, logged out. Now he may use system for few minutes or for hours. To keep session alive till he logged out, I used timer with javascript, it went to server and updated an anthem label with current time on server.