How do I secure an account that is created via OAuth Spotify - oauth

I would like users to register an account on my site via OAuth Spotify. I have the following scheme:
User authenticates via Spotify
Spotify ID and Mail are returned
An account will be created on the website (saved to the database)
The user can log in with his Spotify to access that account
The problem I foresee here is that someone can spoof the authentication by copying the ID of another user and it's mail, am I right? If so, what would be a better way to let an user create an account using Spotify Authentication? Let the user set a password? That seems user unfriendly to me.
So, how can I achieve this?

You can use the access token acquired through OAuth to find the associated username. You can use this as the basis for your accounts instead of a username or password on your own site. The process would be something like:
The User authenticates via Spotify
The Spotify OAuth callback returns a authorization code
You use the authorization code to get an access and refresh token for the user
You use the access token to access the associated User ID and use this as the unique ID for the accounts on your site.
Save an account with the Spotify user ID to your site's database
The user can log in again with Spotify to access their account (it will streamline the process by skipping the Spotify OAuth view, if they have previously approved your site, and are logged into Spotify in their browser)
Since your application will only retrieve the User ID from someone's valid access token, and the only way your application will receive that is if they log in through the Spotify OAuth flow, each account on your site will be linked to a valid, unique, Spotify user.
While looking into this, there are security considerations about using OAuth alone to authenticate users. I would look at this post on Security Stack Exchange and decide based on what level of security is needed for your site.

Related

Oauth permanent token when authenticating via social login

I have a web and android applications. I want both apps to login users using their social media handles. I want to use
google
facebook
twitter
tiktok
apple
I have looked at how facebook authenticates users from the docs here https://developers.facebook.com/docs/facebook-login/web/
and there is userID which i assume will never ever change for any given user.
Since social media handles change, email addresses and usernames, is there a permanent account identifier token that the Oauth specification returns that uniquely identifies an account?

DocuSign - Getting a user ID for a user whose organization admins has pre-authorized the application

Any route requires you to be authenticated as a DocuSign user to use it. With the standard service integration flow, you direct the user through docusign's /oauth/auth flow, use the returned code to get an access token via /oauth/token, then use that token on /oauth/userinfo to get the user's ID which you can then sign and use in a JWT.
Instead of directing users through the oauth UI to get their consent, DocuSign allows organization admins to pre-authorize an application for everyone in the application. No need to send organization members through the oauth flow. Great.
However, once this action has been taken, it's not clear how my application could make requests on behalf of any user, since the /oauth/userinfo route that gives you the user id requires an oauth code that you get by passing the user through DocuSign's oauth browser UI.
More specifically: if the admin of foo.com's DocuSign organization authorizes my app, and bob#foo.com starts using my application, how do I get bob#foo.com's user ID to create a JWT with?
When you say "bob#foo.com starts using my application" what, exactly, does that mean?
Case 1: Bob is interacting with your application. In that case, you should be using a User Application OAuth flow such as Authorization Code Grant to enable him to login.
If your app needs to later act on behalf of Bob when he's not around, then store Bob's user id for later use with the JWT grant.
Case 2: Your app is running in the background (no human interaction). At some point your app needs to starting doing things for Bob by impersonating him. All you have is his email address.
If this time arrives and your app has had no interaction with Bob, then yes, you need prior access as an admin (in Bob's account) so you can look up Bob's user_id from his email.
This second account would be the "admin user account" for your app. The account would need admin privileges to lookup the user's information. Your app would get access to this admin account when your app is installed.
Use the Users:list API call. Remember to encode the email address.
Example:
GET call: /v2/accounts/{accountId}/users?email=larry%2Buser%40foo.com
Re: user_id lifetime I'm reasonably sure that the user_id guid doesn't change for a given accounted user (someone who is a member of an account on DocuSign). I will check to make sure.

Confused about oAuth, creating secure API in Rails

How do I secure my API when I want an app to be able to retrieve app-specific information without a user logged in and when I have an OAuth provider for another section of my API? Can I use the client app's OAuth credentials to hit the API without a user logged in?
I have create an OAuth provider and client using doorkeeper following railscasts 353. I can successfully authenticate a user to my provider app and make requests on behalf of the user to my provider API.
However, a portion of the API is user independent, meaning that the information returned from the API is not specific for a user and therefore a user should not have to be logged in. For example, assume an ecommerce site and items and prices are stored on the provider for multiple clients. I want a client app to be able to securely retrieve the items/prices associated the retrieving app without a user having to be logged in. So if you went to example.com the items would be displayed even if a user is logged in via OAuth.
I have only be able to retrieve this information via OAuth when a user has logged in through OAuth (creating an access_token). Is there a way to use OAuth without having a user present (I've been trying to read about 2-legged OAuth and if that is an appropriate solution)? Or do I need to use Api keys (or Http Basic Auth) for the application to retrieve the application specific data?
If OAuth is not the right solution because I do not have a user present, could/should I use HTTP Basic Auth over SSL and use the client site's OAuth secret key as the API key for the basic auth username?
If you need to authenticate your client apps in you API (without requiring a user specifically) use the Client Credentials flow

Performing Google Federated Login/oAuth2 after initial Authentication

I am trying to support "Hybrid" Federated Login and oAuth2 (using logic from this document) for a webservice which will:
support Sign in using your Google account on my site. That is, from the documentation: You can also choose to use Google's authentication system as a way to outsource user authentication for your application. This can remove the need to create, maintain, and secure a username and password store.
Access the user's Google Analytics.
Here are the steps I have done.
I form my request to https://accounts.google.com/o/oauth2/auth with the scopes (Google Analytics) I want access to.
I Get redirected to google where it has my icon and which scopes I am requesting access to. I grant access.
I get redirected back to the callback page.
I get the tokens (access and refresh), as well as a huge id_token string (which I don't know) and store all of this information in my database.
I then make a call to https://www.googleapis.com/oauth2/v1/userinfo?access_token=xxxyyyzzz to get the user's email and name and store this information in my database too. I also notice it returns a id field which to my knowledge never changes and I presume is some sort of unique identifier. I store this too.
Question: If I go to Authorized Access to your Google Account section in my Google account, it shows that my site has access to "Google Analytics. BUT, it does not say Sign in using your Google account. This is what I am trying to accomplish. I would have thought using the logic would enable Sign in using your Google account. What am I doing wrong? And what would be the applicable call to google so that users can sign in to my site?
If your site has access to something like your Contacts or Analytics using OAuth, you'll never see "Sign in using your Google account". I'm pretty sure that's only if you use OpenID (not OAuth) only for sign-in.
Specifically, OAuth is used for giving you access to APIs to create/update/delete data, while OpenID is for signing in.
If you are asking how to identify user for future logins, you have two options:
Mix OAuth with OpenID, that is called Hybrid. I have described it on this answer.
Use userinfo scope and request userinfo (email, etc.) after successful OAuth authorization. It is described on Google OAuth 2 documentation.
If you mean automatically login to your web site in future visits you can use OpenID "immediate mode" (openid.mode parameter).
When the user is redirected back, you call the second request from your own (server-side?) code, and get their email address. When you successfully get it, that means that the user is logged on. You can add it to the session (e.g. as cookie), and as long as you have it, the user is logged on. You make the user log out by forgetting the email address, so by clearing the session/cookies.
Add this paramter to the https://accounts.google.com/o/oauth2/auth URL call: approval_prompt=force and then the Sign in using your Google account will always show regardless of whether the user was already signed into that or any other account.
So the call would be like this https://accounts.google.com/o/oauth2/auth?client_id=<client id>&redirect_uri=<uri>&scope=<scope>&access_type=<online or offline>&response_type=code&approval_prompt=force

For a hybrid SSO scenario using the Facebook iOS SDK, what's the best way generating a password/key for our own custom user records?

So my intention is to have a login in my iOS app that allows for either our standard email/pwd registration, or login with Facebook. We are also creating rest services to get application info for a given user, e.g. https://url/getPosts/[userId]?userPwd=foo
I've implemented SSO with fb in a web application before but I have some concerns about the security of authentication in a iOS client scenario. The key difference from what I've done before is that in a web app, I was making a server to server call to Facebook to get the access token so I was reasonably assured that the user was authenticated and the web server made privileged calls to the database. In the iOS case, I have the mobile client app making the Facebook iOS authentication request itself and the server has to somehow trust that this user from the client app is indeed authenticated against the matching user record in our database.
My question is how do I generate a durable and secret unique key from the iOS SDK so that I can create and associate a matching user record in our database for users that authenticate only with Facebook. I want this to be seamless so the user would not have to manually fill out another form, and we would just automatically create this matching user record in our db.
I could insert a record into my own users table when they fbDidLogin with Facebook, using the Facebook Id as the unique identifier, and the fb access token as the pseudo password/key for my own user record. I would have to validate the access token with Facebook to make sure it's valid before saving it as a password for the user (the user would never see this password, it would just be passed by the client app during api calls). That way when the user makes a call to our own rest api via the iPhone app we can authenticate and authorize using this secret/pwd/key.
An alternative that would make this whole question moot is to just handle the authorization logic on the client app, and check that there is a valid fb session before making calls to our own apis which I secure with just a single application-wide secret, but that doesn't seem as secure since getting that one secret gives authorization to data on all users. I'd rather authorize at an individual user level. Is that the right choice? Am I being paranoid about iOS security?
The fb access token expires so that might not seem durable, however if I enable offline access that token won't expire but creates a scarier looking oauth dialog window. An alternative to the access token is to hash the fb Id with an application secret key on the iOS client, and use that as the Facebook user's password in our db. However, that again is a single secret key that could perhaps be reverse compiled from the iOS client app?
Design for Facebook authentication in an iOS app that also accesses a secured web service
This post helped me undesrtand it more. If I am not mistaken, the flow goes like this:
User authenticates in iOS app
iOS app takes auth token, sends it to the rails app
Rails app takes auth token and sends it to graph.facebook.com/?auth_token=XXX to get back the user if authentication was successful.
Rails app takes the user info and matches/creates user in own database table. Sends some kind of authentication key back to iOS app.
iOS app saves the authentication key so it can use it to communicate with the rails app.
Let me know if I am missing anything.
Have you looked at the iOS docs for Single Sign On (SSO)? https://developers.facebook.com/docs/guides/mobile/#ios
You can share an app ID across mobile, canvas and web site and the same user auth works for each environment.
Check out: https://developers.facebook.com/docs/authentication/
Facebook Platform provides a number of ways to use the above OAuth flows in different app types, including Websites, Apps on Facebook.com, Mobile and Desktop Apps.
You just need to insert users Facebook key to your database to know if its authenticated with Facebook. Use OAuth at ios side authenticate user take users secret key send it to your rest web-service and save it with users other info.

Resources