I am configuring Azure ACS with "Google" configured as IdP in my application. My requirement is that I do not want the IdP login page to be displayed every time I try to log into my application. I have set my ACS token lifetime to the maximum period so that my token is valid for a day.
First time when I log into my application and I select "Stay Signed In" in Google login page, I am able to log into my application. I now close the browser, reopened the application, I am successfully rediercted to the application home page without any credential request. (as ACS internally uses the session token created intenally which will be used in next requests)
But if I do not select "Stay Signed In" in IdP login page, and proceed the same steps, I am asked for credentials. Any idea why is this happening? Is there a way I can manipulate the session token and validate the ACS token which was earlier issued to me ?
When you select "stay signed in" at Google, it writes a persistent cookie, meaning that you'll stay logged in even if you close your browser. By default, your application's cookie is scoped to the session (assuming you're using WIF). When you close and reopen your browser, the original token and cookie are gone. Your browser redirects to ACS, which redirects to Google, which redirects you back again because of the persistent Google cookie. Running your session using Fiddler or HttpWatch should show that, even when you choose "stay signed in", you're still being sent back to ACS and Google and getting a new token.
It sounds like what you want is your RP to "remember" the user so they don't have to log in again within the token lifetime. To do this, your federated cookie (the one with the token in it) needs to be set as persistent, rather than session. If you're using WIF, this can be done using CookieHandler configuration on the FederationAuthenticationModule (see PersistentSessionLifetime).
Related
This is a general question regarding web session management.
What is the best practice approach to managing session timeout?
Assume a system where a user logs in, a session is created on the server, and a token identifier is sent back to the client (via httpOnly cookie).
If the user attempts some access-based check where the session is validated, presumably it makes sense to update an expiry time on the session in the DB. Does this also mean that when this happens, we should update the expiry time on the session token cookie to match?
This seems like the most obvious solution to me, but constantly rewriting the cookie seems like a lot of overhead.
Any insight into best-practice approaches is greatly appreciated. Thanks!
How to manage session timeout to keep user logged-in, prevent he/she from accidental logout?
To keep user logged-in, it is not necessary to constantly rewrite the cookie. All you need to do is making the session token cookie's expires as Session, then as long as browser is open (client keeps using your site), the session token cookie is valid. Server does not need to know the session expires time (as there is no pre-defined session expires time any more), not mention store it in DB. After user close the browser, the session token cookie is cleared, and session is terminated (invalidated).
Normally, there will be a "session timeout" setting in server, such as session-timeout in Struts2, which kills the session if client doesn’t make any request after some time.
How to make session "validate" even if user closes the browser? That is, how to implement the "remember me for 1 week" feature?
To implement this feature, a new token cookie is used (e.g. RememberMeToken). When user login successfully (possibly enable the "Remember me" checkbox on UI), server will generate a unique random token and store it in DB (together with its expires time for security reason), make it belong to user account. This RememberMeToken cookie's expires time is pretty long (1 week for example), and will be sent back to browser together with login response.
When user close the browser and re-visit the site later (or the user is inactive for long time and the session is killed in server side), server checks session token cookie and find it's missing/invalid. At this point, RememberMeToken will be checked and compared with token stored in DB, if there is a match, server will make auto-login operation for corresponding user, and return generated session token cookie to browser. This all happens in backend, client user won't feel anything.
After 1 week since user enable the "Remember me" checkbox on UI and login, the RememberMeToken cookie is expired, and user need to login again if he/she opens browser and visit the site.
I think that internal mechanism of authenticaton should set a cookie with a token and store the same token on a server and next on every request compare the tokens from the cookie and on the server and if they are equal then user is logged in. I don't know where a server stores token, maybe in Session or something else (not persistent), but I'm sure that after the server's restart the server's tokens's store should be cleaned up therefore a user with an old cookie can't be authenticated. But in a practice after I restart my server a user is still authenticated and have access to pages because User.Identity.IsAuthenticated returns true. It seems to me wrong. Even if I remove this user from my DB (I use Membership) because I don't want this user have access anymore and restart my server, the user is still authenticated. Can anyone explain this?
Source of answer
Here is how authentication process works.
You setup some stuff in your web.config around where the login page is, how long the login is good for and whether or not to use sliding
expiration (should the time be extended if the user is active on your
site)
User comes to your site, enters their username and password.
That information is posted to your server. You take that information, verify that it is correct (authenticate). If it is
correct, the server then issues an encrypted cookie known as the
FormsAuthenticationTicket Note - this could have a different name in
the new Identity stuff, but the same principle.
The cookie's contents includes items such as the user name and expiration date of the login.
On each request, the server looks at the cookie collection for the authentication cookie. If found, it decrypts it, reads the values and
determines if this is still a valid cookie (expiration time). Once it
has the user information from the cookie, the server can use this
information to determine if the user is authorized for the resource
requested (look up by username).
If the cookie is not present, or has expired, or When the user logs out, the cookie is deleted from the cookie collection. Now, if the user tries to go to a resource that is for authorized users only, then the user is redirected back to the login page.
Hope this helps.
I am creating an asp.net web application with "Remember Me" option during Login and it has an Edit Profile module where users can change their passwords. Here is the scenario.
I logged into the website from Machine A clicking "Remember Me". So I am logged in and since a persistent cookie is created I dont need to login the next time
until my forms authentication times out.
I logged into the website from Machine B using the same account details I used above and from this machine, I changed my password. In this case How can I make the user in Machine A to login again? (Since my credentials have changed). The same scenario can happen if someone gets any user's credential and uses the application.
Thanks
You have to save the last credentials modification date in your database.
When a user try to consult a page of your website, you have to check the date specified in the cookie.
You can also make an AJAX system that verify each minute if any changes are done and, in that case, verify the validity of the credentials.
If the latest date is the "last credentials modification", then delete the cookie and ask the user to log by himself.
I have to admit the process of renewing an expired token at the server-side, because the FB user has logged out, confuses me. The solution to handle expired tokens, as presented on this page, would only seem to work if the user was viewing a server page that could prompt said user to re-authorise the app (JS location.href redirection to a FB dialog URL).
What if a server side app has saved the access token because of some processing that will take some time first? If after some hours/days the server wants to post something to the user's wall, using the either the short or a long term token, but the user has logged out of Facebook - what then? Sure, the request will fail because of the logged out status of the user, but this seems to me to also mean the server will have no valid way of posting to the user's wall until they log back in to Facebook (and the app happens to try to post again at the right time).
Am I right here or missing something obvious? Seems a crazy scenario to prevent a server-based application from posting to a pre-authorised user's wall just because said user has logged out (which i'm sure many, many users do on a regular basis). Why does logging out == deauthorising the access token? And, if the user logged back in, does the existing access token become valid again, or is a whole new token required (assume we have obtained a 60 day token)?
Why does logging out == deauthorising the access token?
It doesn’t. A long-term access token doesn’t get invalid just because the user logs out of Facebook!
So get a long-term one, valid for sixty days – and you’re good to go to post or do whatever a few days after requiring the token. If the 60 days are over and the user hasn’t interacted with your app since, then you have to have the user come back to your app to get a new token.
I want to enable Facebook authentication and the FB-Graph in my website, which already has forms authentication. Using http://multitiered.wordpress.com/2010/08/05/getting-started-with-the-facebook-c-sharp-sdk/, I was able to figure out how to login server-side.
However, the problem with this approach is that a secure cookie will not be created, since the call returns the authentication code in the querystring via a callback. This means that the user will have to login every time.
I can see two ways around this:
Store the access token in a secure cookie manually
Instead of the above approach, use the FB JS API to login - this stores a secure cookie with the access token automatically
I would prefer not to use the second approach, as I would like the login code to be server-side.
Which would be the better approach? Am I missing something?
I use the JavaScript method to first authenticate the user, the JS SDK then writes an encrypted cookie (called "fbs_[YourAppID]") when a connected user hits your page; using one of the many Facebook c# SDKs, this cookie can be decoded using your application secret giving you the user ID, oAuth token, expiry date etc.
Then I hook into the AuthenticateRequest event of my .NET application, check the presence of the cookie, decode if it found, and then find a user who has been assigned this facebook ID (your user table must have a extra field for storing the ID of their facebook account).
If a match is found, I write a normal forms authentication cookie for this user, then .NET will recognise them for all future requests. If no user is found, then this is a brand new user who has just connected. Use the SDK again to query the graph API using their oAuth token, get things like their name/email etc and create a new account, then issue a authentication token as normal.
By writing a normal authetication cookie, the user will stay logged into to your site for all requests, just as if they were a normal user.
One side point, when using email address, check for duplicates, and check for the facebook cookie in all requests. For example, an existing registered logged in user may have just connected.