OAuth Callback "Service"? - oauth-2.0

Is there any service available that would allow someone to set up an OAuth callback service?
Example... I direct a user to Google to authenticate for Google Drive. This doesn't always originate from my website.. it could be from another application on a terminal, a user built website that's using my application, etc. The callback is www.callbackservice.com/callback/oauth (instead of something like www.mycompany.com/callback/oauth).
callbackservice.com now stores the OAuth 2.0 code for me to retrieve via cURL, etc..
Most of these services (at least google and ms) allow you to provide a session key (state) and credentials that could be used to retrieve the code. Then I just do another cURL to exchange for a token.
The purpose of this would be so that if for any reason my web server was down there would still be a service out there to keep things going. Or if my company was bought out they wouldn't need to rely on my web server to keep customers happy. They simply use their own systems.
Thanks for entertaining this.. I couldn't find anything about this online, which probably means that it isn't available for security reasons.

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.

Are there any security concerns with sharing the client secrets of a Google API project?

I'm working on a project using the YouTube Data API. The Python script I'm running uses a client secrets JSON file, which I presume is for verifying the account owner. If I am having issues with it and need assistance, are there any security concerns with sharing this publicly? Is it even alright if it's held privately in a private github repository?
If you check the Google Developer TOS which you agreed to when you created your account on Google developer console
It is against the TOS for you to share this file with anyone. This is secret and only intended for the developer or team of developers who created it. This pertains to the entire client secret json file you download from Google developer console or google cloud console.
Again DO not share your google secret file. No matter what the accepted answer stays about how problematic it may or may not, nor does it matter what type of client it is. Sharing the client secret file would be volatilizing the TOS you agreed to.
My corrections for another answer on this thread here
The answer in question has some statements that i strongly disagree with and feel may cause confusion to developers. Let me start by saying I am not an employee of Google, my comments are my own and from my experience with working googles oauth / identity server server for eight+ years and contact with google identity team. I am concerned that some of the information in the answer above may confuse some developers. Rather than just saying dont share them the other question tries incorrectly IMO to explain why it wouldn't be so bad to share them. I will explain why you should never share them beyond the fact that its against googles TOS.
The security implications depend on the type of client secret. You can tell the difference by whether the key in the JSON file is installed or web.
The type of client has no effect upon I how great the security risk would be. If we ignore the definition of what a constitutes a security risk completely and just say that any chance anyone could get access to a users account or authenticate a user on behalf of the project, would constitute to big of a security risk then there is no difference.
Using the following command I could authenticate myself all i need is the credentials file for your project
https://accounts.google.com/o/oauth2/auth?client_id={clientid}.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code
This would only work 100% of the time for an installed application. Why is this bad if i am just authenticating my own user. I could then use my evil powers to send so many requests against the API that the target google developer project would be locked down by Google for spamming.
If i have stolen another users login and password i can login to them from your Google developer project and i have access to their data and Google thinks its you hacking them.
This is a little harder with a web application due to the Redirect URI, However a lot of developers include add localhost as a redirect uri when in development and forget to take it out (Please never leave localhost as a redirect uri when you are in proudcution) . So in the event you have left redirect URI as a valid redirect URI in a web browser client then I can do the exact same thing.
Remember I am now able to authenticate users based upon your project to access mostly my own data. However if you have also set up access to client data for example via google drive I may be able to access that as well. (Note: Im not Sure on this one i havent actually tried.)
If i have manged though man in the middle attack or some other means to get a users refresh token, and I have the client secret file I can now access users data because I can create new access tokens with my refresh token for as long as i want. This is probably a bit harder to achieve.
Web application secrets
If the client secret is of the web type, then yes: you should absolutely not post it, and invalidate it if it gets exposed. This would allow a malicious entity to impersonate your backend and perform actions on your users' accounts on your behalf.
As stated above this will only be the case if the developer in question has left the redirect uri open for localhost or the person who now has your client secret file also has access to your web server. One very important fact is that if you have left localhost open i can then put up my own website using your credentials and set it up so it look exactly like your website. Users then think they are logging into Your super awesome app when in fact they are logging into Hacker Super awesome app giving them access to the users data. Again google thinks its you hacking them.
Installed application secrets
If the client secret is an installed-type secret, then it's less problematic to share privately, as it doesn't grant the sorts of abilities a web application secret does, such as the ability to authenticate as users who grant your application permission to access their data. As the documentation notes, "in this context, the client secret is obviously not treated as a secret."
This is completely false Installed applications give the exact same permissions as web applications there is no difference with-regard to Oauth2 access an access token is an access token no matter if it was created for an installed application or a web application.
As stated above security risk with giving out access to your installed application this is actually worse. As there are no redirect uris with installed applications. Anyone that has access to your client secret file could authenticate users who assume they are you because they are being shown your consent screen. Not only is your Google developer project being hjacked but your reputation to your users who think that they are authenticating to Super awesome app and in fact they are not granting the person who has stolen your credentials access to their data.
I would like to add one last thing. If you give another person your project credentials. The client secret json file. You are giving them access to make calls on your behalf. If you have bulling set up lets say against google maps api. You will be charged for the calls they make.
I hope this helps to clear up some of the confusion related to the accepted anwser.
Yes, this is a problem. It's called a "client secret" for a reason. If it does become exposed, you should take steps to invalidate it and get a new one so that someone doesn't try to impersonate you.
Short answer: the security implications depend on the type of secret, but you should not share it publicly for other reasons, including the Terms of Service, which state that:
You will keep your credentials confidential and make reasonable efforts to prevent and discourage other API Clients from using your credentials. Developer credentials may not be embedded in open source projects.
The security implications depend on the type of client secret. You can tell the difference by whether the key in the JSON file is installed or web.
Web application secrets
If the client secret is of the web type, then yes: you should absolutely not post it, and invalidate it if it gets exposed. This would allow a malicious entity to impersonate your backend and perform actions on your users' accounts on your behalf.
Installed application secrets
If the client secret is an installed-type secret, then it's less problematic to share privately, as it doesn't grant the sorts of abilities a web application secret does, such as the ability to authenticate as users who grant your application permission to access their data. As the documentation notes, "in this context, the client secret is obviously not treated as a secret."
You still should not post it publicly on GitHub, a Stack Overflow question, or other public places, as posting it publicly increases the probability of someone copying your code in its entirety or otherwise using your client secret in their own project, which might cause problems and likely would run afoul of the Terms of Service. People trying to reproduce your issue could pretty easily generate credentials to drop into your code—credentials are a reasonable thing to leave out of a question.

Is there any way to combine client-side and server-side Google API authentication?

Currently I am implementing an Ionic application that the front-end is on the mobile devices and the back-end is on the server. (So there is a connection latency between the device and the server) And my application is using the Google services (like Gmail, calendar, etc) by connecting to the Google API.
Currently the architecture is:
Device <==> Server <==> Google API
This is using the OAuth 2.0 server-side authentication. It works but the connection latency is way too long and feels like going back to the time when we have the dial-up internet connection.
I tried to use the OAuth 2.0 client-side authentication, which is:
Device <==> Google API
This is faster but it has 2 problems:
Even though Ionic packaged the front-end code into an application, I still have concerns that the rule "Everything in the front-end is visible to everyone" stays. (Did not find an evidence to prove or disapprove this hypothesis)
Google API OAuth 2.0 only issues flows to the client-side authentication, and flows expire very often, I don't want the user to grant the permission again and again.
So, I was wondering if it is possible to do the following:
Use the server-side authentication to store keys/credentials (I'm using Django as the back-end, which is Python) and the front-end gets keys/credentials from the server and proceed Google service using JavaScript codes.
I know this is late to the party, but I'm going through this now. I think there are 2 ways to set this up, but neither are perfect.
Use server-side flow to authorize all the scopes you'll need on either the server or the client. When the token is obtained, pass it to your client. The down side is that the client now has a token that has access to more APIs than needed.
Create seperate authorization flows for both the client and server. This would mean the user has 2 authorization prompts, which is no good. The good thing about this approach is you could ensure the client has limited scopes, but the server could still handle the larger tasks (moving Drive files, sending emails, etc.)
In my case, the client would just need read access to the Contacts API, whereas the server needs full Drive access.
If anyone finds a combination approach, where only 1 authorization is needed, but the client and server have seperate scopes, that'd be the ideal situation.

How to leverage oauth to implement SSO for micro service apps

We want to establish SSO between microservice apps,
Eg: In a e-commerce site if user logins to main app,user should be automatically allowed to access cart app connected to it, which is a micro service.
I searched Oauth spec but I could find any relevant answer specific to my case.
some of things which differ wrt Oauth are
User need not to authorize resources(cart app) against Identify provider.it should be done seamlessly in backend.
we don't want to use outside Identify provider like facebook,google,Main app(from eg above) should act as identity provider.
Questions
1.Is there a standard way(procedure) defined in oauth to handle these kind of authentication/authorization.?
If not what are the most popular alternatives ?
Other info:
Ours apps are build using Ruby on Rails,if you know any good gems please suggest.
I found couple of questions(1,2) related to this but they much broader. Even google is also not helping,so please don't mark this question as duplicate.
If you do want to use SSO, let all your services accept the same token, returned by Authorization server when user log in. Encrypt it and put to cookies for example - in this case your web frontend will authenticate user by validating that token against Authorization server and return user-specific content.
The same applies to cart service - it can get username by token and return user-specific cart items.
Pros: User can't access other user's data by design, user logout disables every service.
Cons: You will need "superuser" or additional API for background or analytical tasks.

Use OAuth 2.0 Tokens to login to Salesforce.com

Currently we are not using OAuth with our apps but we are working on making the shift, we have direct login and capture the user/pass that was entered and store those. We then turn around and use the stored credentials for a feature that allows the user to open a record within Salesforce.com, we pass the user/pass in to the login endpoint along with a starting URL to the specific record, this works great and is a well liked feature as it is a simple SSO from the App to Salesforce.com where the user can see all data that may not be visible within the app.
Moving to OAuth 2.0 and using the standard webflow, we no longer can capture the user/pass, which is actually a good thing as far as security is concerned. We would however like to keep this functionality, is there anyway of SSO'ing into Salesforce.com by passing along one of the OAuth tokens or some kind of sesson id?
After reading more and thinking about what OAuth accomplishes I feel like this probably isn't possible being that the tokens obtained are meant to be used only with the API and not with the front end system. I hope that I am wrong though and there is a way to login to the front end using these tokens.
EDIT
Ok I am editing to hopefully make this more clear. Currently user's authenticate using the login() API method with their user/pass, we store this user/pass locally (not ideal). We then sync a subset of data that the users can access anytime within the app, being that it is a subset, we have a feature to "SSO" to the Salesforce.com front-end. This simply opens Salesforce.com in a web-view (UIWebView) using the URL https://ns8.salesforce.com/?pw=PASSWORD&un=username#example.com&startURL=/recordId. This will log us in to Salesforce.com and open the specified record.
Moving forward we want to use OAuth 2.0 with the web flow so that we aren't handling the user/pass and so that we do not have to deal with Security Tokens or opening specific IP ranges to allow login without a Security Token.
With that said, is there anyway to use the tokens/credentials received from the OAuth authentication to open Salesforce.com, automatically log the user in, and goto a specific record?
I may have mis-used "single sign on" before, but in a sense, this simulates an SSO from our App to Salesforce.com, in that our users can touch a single button within the app and be logged in to the Salesforce.com web interface.
When you request an OAuth token, you can specify what scope it has, options include api only (the original type of tokens), or other options which include the ability to use the token with the UI pages. (see the scope parameter detail in the help). One of the still missing peices is a way to bootstrap the UI with that token when all you can do is tell a browser/webview to goto a URL, but a widely used (but unsupported) way is via frontdoor.jsp, e.g. you'd open https://{instance}/secur/frontdoor.jsp?sid={the_Access_token}&retURL={optional_relative_url_to_open} remember to URLEncode the 2 values.
So I think you are saying your application uses the SFDC username and password to just authenticate to retrieve a record from SFDC to display in your app?
IF this is correct - which I think it is - then you could just use the standard Salesforce Single Sign On system to authenticate. There is a guide here which outlines the process of setting up a SAML SSO system with Pat Patterson writing an interesting feature on how the security system works here. He has also written a great blog post on DeveloperForce here about the nitty details of OAuth in general for Force.com and not just the SAML setup. I have used the OAuth system in an iPad app against SFDC and it works quickly and easily. I can't see why your system should be unable to use the protocol as you desire.
Direct access into Salesforce is a key benefit of SSO and definitely provided. I'm not sure where you read that SSO in Salesforce is API only. From the SSO PDF pbattisson linked for you:
With single sign-on, users only need to memorize a single password to
access both network resources or external applications and Salesforce.
When accessing Salesforce from inside the corporate network, users are
logged in seamlessly, without being prompted to enter a username or
password. When accessing Salesforce from outside the corporate
network, users' corporate network login works to log them in. With
fewer passwords to manage, system administrators receive fewer
requests to reset forgotten passwords.
OAuth 1 & 2 are both supported, though I'm a fan of OAuth 2 since 1 has really finicky additional steps involving the order of parameters and their encoding sequences. I recently wrote an Apex-Twitter integration and quickly realized it wasn't going to be as easy as Facebook, which uses OAuth 2.0.
But in your case it sounds like you just want to provide users with the ability to actually login to Salesforce and go to a specific landing page once authenticated. This is definitely doable.
Good luck!

Resources