Best way to seamlessly & silently authenticate with a second webapp while logged in to a first? - authentication

Third party app (A) needs to link users to our app (B) and log them in behind the scenes.
Both apps work independently with their own auth systems. Users share a common unique ID, but have different authentication tokens (username/password/key etc) at each app.
The two complicating factors are as follows:
One app B user may associate with two app A users (e.g. both accounts at app B would redirect and login to the same app A account)
The app B user may not actually have any existing auth tokens, only their personal record and user ID, but we still want to be able to log them in if they are coming from app A.
My first thoughts were OAuth - but I don't think it will work as some users don't have app B accounts and thus won't be able to log in to grant app A access (see point 2 above).
The simplest way I have come up with is:
Each app has a pre-shared key e.g. "LOLS"
Common hash algo generates indepentent identical tokens e.g. hash(PSK + UID)
App B stores hashed tokens for each user
App A sends POST with UID and hashed token to App B, which uses it to identify and auth against a user
The problem with this is that it's hideously insecure. Anyone with knowledge of the pre-shared key (any system admin) and a user's ID (once again, any system admin) would be able to authenticate as ANY user, which is unacceptable.
Does anyone have any solutions? I'd prefer existing standards but am open to customised implementations. We can't really do much to app B other than to get them to use whatever API we provide.

I've faced situation similar to this many times. There have been a variety of solutions we've explored, here's one of them.
You produce a webservice for them to call. This could be something you lock down however you like, including by limiting access to their IP address at the firewall. They post the UID to your webservice, which inserts into a table on your end and hands back some sort of random token (we randomly generated a guid). Your table associates the token with the UID (in plaintext) they sent and a datestamp.
Their application sends the random token to you instead of the UID, you use it to look up the UID, and use the timestamp to make sure the random tokens are expired after a minute or so. Even if someone looks through your table somehow to get the list of UID's recently attempted, it doesn't let them authenticate unless they can pull it off real fast!

Related

Database structure for multiple authentication sources of users in a web app

I'm trying to work out how to structure a database schema that allows me to have multiple authentication sources for the same end-user.
For example, my web app would require users to sign in to utilize many of the functionality of features of the app. However, I do not want to be responsible for storing and authenticating user passwords.
I would like to outsource this responsibility to Google, Facebook, Twitter and similar identity providers.
So I would still need a database table of users, but no column for a password. However, these are authenticated would not be my concern. But I would still need to somehow associate my user with the identity providers user id. For example, if my user signs up with Google, I would store the users Google ID and associate this with my user. Meaning next time the user makes an attempt to login and is successfully authenticated at Google, I would make an attempt to find any user in my system that has this associated user id.
I've been trying to look for some common and recommended database structures, with no luck. Maybe I'm searching for the wrong terms for this because I cannot imagine that this is an uncommon way to do it. StackOverflow seems to do something similar.
The way I imagine it, it would allow me to associated multiple authentication sources for one app user. Meaning once I've signed up with Google, I can go to my settings and associate another account, for example, a Facebook account.
How should I go about achieving this in a flexible and clean way?
Thanks.
You need to know what data you have to save in your db to authenticate a user with a third party login.
For example, once I used Google to login users in my app, I save Google user id first time a user logs in and get data the next time.
You could have an entity with third party providers, so you will create a table with 2 values, user_id (your user data) and provider_id (Google, facebook, twitter...).
If you are going to use just one provider then you could add provider_id field to your users table.

How to implement a one time authentication mechanism?

I'm trying to create a website to authenticate users through the use of a throwaway password where the assumption is that the user might not use the website again (basically a one time access).
I have done my research on OTP and various solutions to authentication but these don't seem to fit my requirements, most of them seem to rely on users having login credentials to the website whereas my system would allow them access without the need for registering.
The implementation of passwordless authentication by Auth0 seems to fit what you're describing. Even if you were not considering a third-party provider it may be useful to go through the documentation.
Basically, a user can login to a site without any need for a sign-up process. They can do so just by requesting that a one time code is delivered to them, for example, either by email or SMS.
This way, they can get quick access without having to setup a user and in the event that they do come back your application can recognize this because they will most likely be using the same mechanism, that is, you can use the email or mobile phone as the unique identifier.
Disclosure: I'm an Auth0 engineer.
If you do not require your users to register, why do you need authentication at all?
Why not just set a cookie with an unique identifier on the first visit? You can store data at the server side associated with that identifier. Keep track of when you last saw the user, and if they do not return within a certain period, you can delete any data you stored for that user.

User Authentication with Cookies Only

I am planning to use only cookies (and not sessions) to authenticate users around the private section of my website. I want users to stay logged in indefinitely, unless they logout themselves. It will work like this:
1. Upon successful login I generate a random hash and store it as a HTTP cookie on the user (using SSL). I also store the hash in my database, along with the user id and the user's device.
2. Whenever a new page is requested I check to see if the user has a cookie. If he has I get the hash and search it in my database. If I find a match and the device is the same I assume it's the user and give the page. If I can't find the hash or the device changed I assume it's not the user and ask for login again.
My question: would this method be acceptable, security-wise? I can't see why this would be less secure than using sessions (keeping the users logged in in both cases), as in the end the risk is the same, which is having an attacker discover the hash to impersonate the user. My defense against this is tracking the users device, so the attacker would need to discover the hash and have the same device.
Thanks for your feedback.
What you're describing is basically the session functionality offered by most languages/frameworks.
Just make sure your hash values don't use the time the user logged in as a source of entropy, ie. don't use h(username + login_time) because this could be brute forced fairly easily if the attacker knew the approximate login time.
What language / framework are you actually using? You'll find in most cases there's an option to use the session "functionality" with a persistent cookie (rather than a session one) which would save you implementing this from scratch and possibly creating additional security concerns.

When using Token based authentication how should you handle multiple tokens/expiry

I'm reading/learning about token based authentication and I'm understanding it to a degree but the following questions have arisen.
If you log into site A you are given a token, this token will expire 24 hours after creating it.
You also visit Site B which calls an API from site A that allows you to give site B access to your information stored on site A. At this point a token is passed to site B to use for 24 hours.
Is this the same token? (So if you logged into Site A via site B, 23hrs59mins after logging into site A directly you would only have a minutes access to your info through site B before needing a new token?)
If its not the same token and you store your token in a table which links it to the user would you have multiple tokens per user?
Is it wise to to generate your token(s) as a random uniquely generated code and store it in the database along with the users log in details or is it better to create a token which takes a combination of the log in details and encrypts it (if so, how do you change the token each time).
Is this the same token?
Well that depends on Site A. Using the same token would mean that Site B has access to everything that your login on Site A allows you to access. If this didn't seem appropriate, then Site A would generate a new token with a more limited access. In this case, there would be multiple tokens per user.
So if you logged into Site A via site B, 23hrs59mins after logging into site A directly you would only have a minutes access to your info through site B before needing a new token?
If it expires 24 hours after creation (which you mentioned), then yes. Often the expiry would be updated upon every access though, so this might renew it for another 24 hours.
Personally, I would (and have) generate token as a random uniquely generated code. I think either would work though, and I'm sure you can find lots of opinions out there, like
here or here.

Checking for Correct User in JavaScript SDK

I am thinking of tying in a Facebook JavaScript-based application with an existing website that has it's own user accounts, but have a question about a specific user situation.
The website is run almost 100% of the time from 'shared' computers, like those found in a career center. User A comes to my website, signs into the site and then authorizes the Facebook app, which stores their session in the browser, along with, effectively, signing them into Facebook.com.
User A now leaves my application by signing out of my site - but not closing the browser.
User B arrives, logs into my site with their login, but the Facebook session is still active (due to the browser staying open), so any FB app integrations I've included will show as if it is still user A, correct?
So the question is, what are the recommended ways to deal with this? Two options come to mind:
When the user signs out of my website, I fire an FB.logout call, so that all of the sessions are killed. Pros - I can ensure that user's signing into the site will not have old sessions hanging around. Cons - a user who is returning shortly after leaving will have to re-login to FB as well as my site to see the FB integrations - I'd love to avoid the user ALWAYS having to do two logins. Secondly, forcing the FB.logout when they leave my site kills any active sessions they have at facebook.com, which makes for a bad user experience as they would not 'get' why logging out of my site has anything to do with facebook.com, and will then have to re-signin to facebook.com.
The second option would be that when the user authorizes the FB app, I take their member ID and store that locally and persistently (database). Then, when a user returns to the site and signs in, I check their FB auth status, and if logged in to FB, pull their member ID and check it against the one I have stored locally. If they match, I have the correct user, if not, I do FB.logout and have them sign in to FB. Pros - this should ensure I always have the correct user to the site. Cons - not sure if getting, storing the member ID is feasible.
Any suggestions or pointers to the 'best practice' when it comes to ensuring that the current user is indeed the one associated with the FB account, specifically in this 'shared computing' situation where sessions may overlap?
Thanks
The second option looks to me to be the better choice. You can indeed store the users facebook id. By storing it locally i'm assuming you are talking using a cookie; however storing in a database is just as feasible.
Facebook user id's should be stored with a BIGINT(20) data type - such are the recommendations from facebook.
Taken from the user section of the facebook api refrence :
Looks like they changed their recomendations...