Assessing login state for each request when authenticated using OpenID, OAuth and/or OAuth 2.0 - authentication

I'm in the process of building an expanded login/signup area for my website which includes OpenID, OAuth (Twitter) and OAuth 2.0 (Facebook) sign in options.
Once a user has authenticated successfully and I've stored their access tokens in my database and written a cookie linking the user to their login state, what best practice should I be using to determine that the user's access token is still valid? It seems that having to call the authentication provider for every single request to my site would slow things down for the user and I can't imagine that is what other sites are doing.
My guess is that I should store a cookie which is valid only for the current browser session and thus that cookie will expire when the user closes the browser, forcing a new access token to be generated on the next request (and a new cookie to match). I would also expire the cookie early if the user explicitly logs out.
The only question I have of course is if, for example, the user has my site open in a tab, then they open their authentication provider in another tab and sign out of that site, but continue to browse my site, they won't be logged out of my site, even though technically they're supposed to be able to log out using the third party provider.
Is this one of those "it doesn't really matter" scenarios, or am I approaching the whole thing the wrong way?

Definitely the service providers do not want you pinging their service for every request that comes into your service. Even Google balks at the thought of that. You could set up some kind of a timeout to check every 5 minutes, but I think your idea of a session cookie is the ideal one. But yes, it depends on what you're trying to achieve.
If you are just using these services to log the user in and that's it, then throw away the access token you have as soon as you verify the user is logged in and set your own session or persistent cookie. You don't need their access token any more.
If you do want to access the user's data on these services, then of course keep the access token around. But you still probably should maintain your own concept of whether the user is logged in. If I recall correctly these access tokens are typically long-lived (in OAuth 1.0a anyway) and they won't help you when the user returns to determine whether the user is who they say they are unless either you have your own cookie or you send them through the login service again.

If you are just using OAuth / OpenId for login purposes, I don't think you should worry about any of it.
What you should worry about is if your users are who they say they are as their (OAuth/OpenId provider) users.
If your website intends to interact with Twitter and Facebook, that's a different matter, but still it pretty much solves itself. When you try to interact with FB, while your user has logged out of there, FB will prompt your user to login again.
Bottom line, I think it's really a non-issue.

Related

Ionic 3 App - Keep logged even when app quits

How to keep logged in application even user closes app? Log in only if user logged out prior to closing application?
I would avoid storing the users' passwords at all costs. It's a bad security practice, not to mention your app would likely not know if they changed their password out of band from your app/session.
If you are using a common token-based authentication, then you can use the concept of Refresh Tokens to keep a user logged in. Effectively when the user logs in the first time, you also request a Refresh Token. This refresh token can then be used in the future to get another access token without requiring a username/password. See this link for an example implementation from Auth0. That's the product we use.
Additionally, you should likely not use Refresh Tokens for web-based logins. For web-based logins it is more common for a user to log in on public devices (or someone else's device). So keeping them logged in for those scenarios may put your users at higher risk.

How do I keep the user logged-in with Implicit flow?

From what I understand, the end-result of the implicit flow is the access token, which allows the client (in my case a JS SPA) to authenticate into resource servers (APIs).
The access token is usually only valid for ~1 hour, then it expires - making it useless.
What should my JS app do then? Redirecting the user back to the auth server is unrealistic since then the user will have to reenter their credentials every 1 hour!
I also know that the implicit flow doesn't support refresh tokens so I can't use those either.
Is there a way to persist the user's login? How do things like Facebook keep you logged-in indefinitely?
Just to clarify, you are asking about the Implicit flow which is detailed in the OAuth 2.0 RFC rather than OpenID Connect which deals more with authentication of a user?
With the implicit flow you do have to regularly call the authorisation endpoint to obtain a new token, but if the user remains logged into their identity provider then they should not be prompted to resubmit their credentials, and the token will be returned as a hash fragment in the redirect uri, with no user interaction required.
You can use an AJAX call to get the token on a back-channel so your SPA app user experience is not affected by the need to get new tokens.
To address the points you highlight in your question:
The access token is usually only valid for ~1 hour, then it expires -
making it useless.
Correct!
then the user will have to reenter their credentials every 1 hour!
Not necessarily.
If the user stays logged into the identity provider (e.g. facebook, google) then there will be a browser cookie between the user and that provider. This effectively means the identity provider does not need the user to re-enter credentials. The authorisation server should be able to return you a token with no interaction required.
Is there a way to persist the user's login?
You can't control it from your SPA. It's totally dependent on the user staying logged onto the identity provider. If they stay logged into facebook, google (or whatever IDP you app uses) then you should be able to get tokens non-interactively.
This article nicely explains how the implicit flow can be implemented.
If the session at the OP is still active (via a cookie perhaps), then OpenID Connect has a mechanism to refresh tokens in a (hidden) iframe: prompt=none.
According to the spec, when sending this flow...
The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent.
prompt=none is also referred to from the Session Management specification.

Why use OAuth in mobile HTML5 application that will use REST?

I am exploring the possibilities of a banking mobile HTML5 application. It will be contacting with the main server via RESTful API. Very often I hear that people are using OAuth in their mobile apps to access APIs. For example, SpringSource's html5expense demo app.
So I don't fully understand why bother? Couldn't the user just login in a standard way, receive a cookie with session id (or in case of Play framework, session data), that will be used to identify user when the app makes requests to REST?
Oauth is usually a lot more secure than most BASIC AUTH, or "logging in in a standard way" approaches (and OAuth is becoming more and more of a standard).
When you login, through most "standard" ways, the user enters his username & password, into the application, and username/password are then often either stored locally, or transferred to the application, to then potentially be relayed to a "main server" that for example provides the API. So the user will have to enter his very secret login information (e.g. for banking?), into a client, app or system he doesn't know or trust...
With OAuth, the user is directed to a login page of the owner of that API .. e.g. his bank for example, where he logs into the secure login page that he knows and is asked for his consent that the application "xyz" would like to access his data.... The application that has requested that access, is then given a token with which it can access the API without needing to know the username and password. That way the username/password is only entered once, at a location the user trusts.
Furthermore, the user could later log into and admit page .. (the bank app? or and admin frontend), and delete the given access right to the API, and so stop an application accessing his information, without having to change his password.
Beyond the effect of being actually safe, using something like OAuth, for a banking app also makes sense as it will give people more confidence if modern security techniques are applied. It makes it also feel safer.
If you are not going to publish your API to third party developers; there really is no reason to bother with OAuth.
The biggest reason OAuth exists is to enable integrations with your API without your users having to give out their username and password to a third party. Other reasons is that it makes it possible to put a time frame on third party access to resources, or to scope access.

OAuth - Binding local user to 3rd party

I'm working on a mobile application, in which, the user can go for Facebook, Twitter or Foursquare authorization (via OAuth) rather than creating a new account and password.
The problem is, I'm not sure what should I store in my DB to point a 3rd party account. The auth_token, acquired from OAuth process seems to expire or change in some situations (like when the user changes password). So, it's not a good option.
What would be the long term option? I mean, even if user unauthorized my app, then authorizes it back, I would like to be able to find out the local user corresponding to them. Should I use the respective API's of each website and dig out user_id and store it? That would be consistent in between sessions I believe.
Any suggestions?
Thanks.
When you are getting the authorization from the sites, you need to only store the access_token (and refresh token if OAuth 2.0). With a OAuth 2.0 access_token, it will expire occasionally and you will need to use the refresh_token to get a new access_token. The user changing the password will not change the token, but the user would have the ability to revoke the token at any time.
Since they have to go through your mobile app to get the OAuth authentication, you should be able to link them together easily.

Can OAuth access tokens be used for securing Permanent access to an account?

Can I use the request token given by the OAuth provider and use it forever? I am looking to build a service which interacts with the Delicious api and looks for updated bookmarks every fortnight. I was just wondering if I could use the same request token instead of asking the user to authenticate again and again. If I cannot, which is what I guess the answer will be, what would be a best practice for such an action?
My last option would be to expect users to give up their delicious username and passwords to me, in which case, my job becomes extremely easy.
This is implementation-specific - you'll have to see what the Delicious docs say about the token. It may expire, have limited uses, or have side effects when used.
Most OAuth implementations will probably expire their tokens at some point to reduce the number of valid tokens they have to keep track of.
In general, user-agent help should make this less of an issue for SSO authentication systems - when the user shows up without a valid token, the browser is redirected to the authenticator, which looks at stored credentials on the browser (usually cookies) and redirects the user back with a new token, without any user interaction. This can be more complex for OAuth than for OpenID, since it might not be appropriate to issue a new token if it does more than authenticate. And since the authentication/authorization process is implementation specific, you need to be able to enter new credentials unless you know that the token will be valid.
probably not answering your questions directly, twitter oAuth allows to have a permanent request token.