Different oauth2 native/web client ids for same app - ios

I am accessing Google APIs from a native iOS app (using gtm-oauth2) and from my web app, which each have different client ids.
When I try to refresh the access tokens with refresh tokens created by a different client id of the one it was initially generated with, I get an authorization error.
I don't want users to be required to allow access to my app more than once.
Is it possible to make both client ids work interchangeably?
Or is there a way to use the web's client id on the iOS platform (with gtm-oauth2 or without)?

I think you need to understand a little about how Oauth2 works.
When a user grates you access to there data they are granting it to your Application. In order to do that Oauth2 needs to know what application is requesting access. The application is identified to Oauth2 by its client id. The Access token Refresh token is made for the specific application.
By having two different client ids you have two different applications and the refresh tokens cant be interchanged
I haven't tried this but it might work. Have you tried using the client id from your web app in the IOS app? If it does / or doesn't work I would love to know for future reference.
I hope this helps.

Related

What's the best way to use OAuth to manage access to a suite of applications?

Please forgive my ignorance on this topic. I've been a developer for a long time, but there's a huge gap in my knowledge and experience when it comes to authentication & authorization protocols and proper handling of tokens.
We've got a whole homegrown suite that consists of:
4 web apps (2 in Ruby/Rails, 1 in Elixir/Phoenix, 1 single-page React)
1 image server (serverless app written as an AWS Lambda / API Gateway)
1 custom data API (also serverless Lambda / API Gateway)
We also have an Amazon Cognito User Pool connected to our backend identity provider to authenticate users and generate tokens.
All but one of these allow some form of anonymous access; the other is only available to logged in users. If a user is logged in, they all need to access the user's profile info from the ID token, preferably without initiating another auth flow. Our backend apps may also need to make use of the access token, but obviously we wouldn't be handing that out to to the SPA or public API consumers.
My first thought is to store the tokens in a key/value store on the backend, and have a short-lived, encrypted JWT containing a unique session ID set on the shared domain that all of the backend apps have access to, with the key stored in a config secret. By decoding the session ID, they can get what they need from the data store. The API would also refresh when necessary.
I also know that API Gateway can use a Cognito user pool as an authorizer, but I'm unclear how I would make that work while integrating it with the rest of our apps and requirements above. Sometimes requests to the API are made from the browser (in the React app, for example), and sometimes they come from the backend of one of the web apps.
The image server and API are used by our apps, but are also documented and accessible for other people to build their own applications on. But they would have to register their apps as OIDC clients to receive any profile info from logged in users.
I'd love some advice on how to make all of this work, or at least pointers toward resources that might help make it less dizzying.

Grant access to api from native client

I have a mobile app using Azure AD B2C which works fine. I can create an account, login, forgot password etc. That's all fine.
The mobile app stores data on the device.
The mobile app should also be able to push data to a remote database and trigger various functions via a .net core web api.
The mobile app should only be able to do that if it authorises itself successfully with the api using the credentials, or access tokens, it has from the login.
I assumed that this could be implemented easily (because, why couldn't it be?)
But now, after weeks of searching, hours of video-watching, 10's of aborted [test] projects, & 1000's of user accounts; I'm not sure whether the thing I want to do is a thing that can be done or should be done.
Thoughts?
Yes, this is of course possible :)
You can check the code samples for some examples of how to do it: https://learn.microsoft.com/en-us/azure/active-directory-b2c/code-samples.
Your mobile app can acquire an access token for itself.
You'll have to define in B2C that your app contains an API, and then define the app ID URI (an identifier for the API, not a URL).
You can then define scopes that API exposes.
These can be different permissions that applications calling the API can have.
In your mobile app you then acquire an access token using those scopes.
This token can then be passed to HTTP requests to your API, which the API has to authenticate.
Do ask if you want to know about something specific.

Can we use google youtube data api without OAuth

After reading the documents of Google API. I know that if a project we create needs to access private data, we should use oauth. But here is my situation. we will open a business account in Youtube, and we will create a project to push videos to our own account, we don't need to operate other user's' account. Can we use google youtube data api without OAuth?
There are two ways to access private user data with Google APIs.
Strait Oauth2. where you have a consent for asking the owner of the account if you can access it
Service accounts which are technically pre authorized by the developer.
Normally I would say because you are only accessing the one account that you own, use a service account. Unfortunately the YouTube API does not support service account authentication.
Due to the lack of service account support you will have to use Oauth2. I have done this in the past.
Authentication your script once, using a server sided language of some kind. The Authentication server will return to you a Refresh token. Refresh tokens can be used at any time to get a new access token. Access tokens are used to access Google APIs and are only valid for an hour. Save this refresh token someplace. You will then be able to allow access the YouTube account in question when ever you like.
Note: You will have to watch it. Refresh tokens can on rare occasion become invalid. I recommend having a script ready that will allow you to re authenticate the application again storing a new refresh token. Its rare that it happens but it can happen best to be pre-paired.
Oauth Play ground
Part of the point of Oauth is that it identifies your application to Google though the creation of your project on Google developer console. Things like quota and access to which APIs is controlled though that. If you spam the API they will know and shut you down. (never seen this happen)
When you request access of a user it pops up with the name of the project on google developer console. This is identified by the client id and client secrete for that project on google developer console. When I use oauth playground I get asked 'Google OAuth 2.0 Playground would like to ..'
So by using playground you are using Googles client id and client secrete to create a refresh token for yourself. If N other devs are also doing this the quota for YouTube may be used up in the course of a day. Also security wise you are now giving that project access to your data. Ignore that for a second what if google suddenly decides to remove change the client id or generate a new one. Your refresh token will no longer work. What if random dev X is using it as well and he starts spamming everything and the client id gets shut down (Think this happened last year) your going to have to wait for google to upload a new client id for the one that has now been banned.
Google OAuth 2.0 Playground might seam nice but its not for daily use IMO its good for testing nothing more. Create your own project and get your own access its not hard just requires a programing language that can handle a http Post.
My tutorial Google 3 legged oauth2 flow

Rails and OAuth2

More of a theoretical question here - how can you get around using OAuth when you don't want to use it, but are using an API that requires it.
For example recently I was looking through the Bing Ads API and noticed they now require you to do OAuth as part of the process. Which makes sense if you're making an application that allows a user to control their Bing Ads account via your app. However, let's say you wanted all of your users to interact with one Bing Ads account.
Is it possible to hardcode all of the OAuth pieces in the background and just use the same authentication for every user to essentially send their stuff to the same Bing Ads account.
- If so, what sort of negative impacts would there be on that?
While it is simply not possible to get around using OAuth if the API requires it, OAuth can be used for more than just the "access delegated to client by current user" use case. As you suggest, if you want all users of your app to interact with your Bing account ("on your behalf" on OAuth speak), you can certainly do that with OAuth.
For an OAuth 2.0 implementation this would mean that you obtain an access token and preferably a refresh token in some way for your app, e.g. by you yourself going once through the Authorization Code flow (also, some services allow you to generate tokens in their web UI). Then you would "hard-configure" the token(s) in your app and use it/them to talk to the Bing API.
If a refresh token is included as well as an access token then your app can get a new access token in the backend whenever the old one expires without you (or your users) having to go through that initial flow again.
Be aware that this is not good practice for mobile apps, where you would have to distribute your app with the tokens embedded in the binary packages. Those tokens could easily be grabbed through hacking/scanning those binaries. But when the tokens are used in a backend service and never exposed in the front end, this is a perfectly valid scenario.

Sharing Facebook Access Tokens Across Apps

I want to provide a service using the facebook api to third parties. Is it possible for us to share access tokens? If the third party gives my service a user's access token, can I access that users data even if my app_id & secret do not match the app that requested it?
Should I have the users go through a separate oauth flow on my site even if they have already completed it for the other third party?
Thanks.
-ken
Even that user access token is issued only for one app it can be easily used from any other application.
Example:
Get access token for "Graph API Explorer" application here https://developers.facebook.com/tools/explorer/?method=GET&path=me and make a request - you will see your data.
Copy access token and open other machine|browser and go to https://graph.facebook.com/me?access_token=[access_token] - you still able to retrieve information about your Facebook user!
Here https://developers.facebook.com/docs/concepts/login/access-tokens-and-types/ it mentioned that
Our Data Policies explicitly prohibit any sharing of an Access Token for your app with any other app. However, we do allow developers to share Tokens between a native implementation and a server implementation of the same App (ie. using the same App ID) as long as the transfer takes place using HTTPS.
Regarding:
Is it possible for us to share access tokens?
and,
can I access that users data even if my app_id & secret do not match the app that requested it?
The answer is No. From the specs OAuth2 section 10.3:
Access token credentials (as well as any confidential access token attributes) MUST be kept confidential in transit and storage, and only shared among the authorization server, the resource servers the access token is valid for, and the client to whom the access token is issued.
Should I have the users go through a separate oauth flow on my site even if they have already completed it for the other third party?
The answer is Yes. If you're using facebook as authorization server, and you restart the oauth flow again, your user will only need to approve your other app (third party).
Each access token is issued only for one app - it cannot be used with different application IDs.

Resources