We are starting to move our self-hosted internal services to the cloud. We've migrated some services to Google apps, but we have several application we developed ourselves that we would like to move to Heroku.
When we hosted them ourselves, authentication wasn't a problem, since being on network (physically or through VPN) was proof enough. Now that we're moving them to the big bad internet, we need some sort of login. Since all of us have google accounts, it makes sense to use them for that.
We've played with the Google OpenID option, however, this doesn't give you any information beyond the name and e-mail address, which we would then have to look up in the provisioning API, to check if that e-mail address belongs to a user we know of. That seems the wrong way to do it. Also, I'm not 100% sure that you cannot add any email address to any Google account.
I've read everything about the Google Auth APIs, but that seems to be about giving access to Google services, not our own.
So, is there a way to do Authorization (not just SSO/Authentication) with our Google Apps accounts?
If you're trying to use Google Apps as an Identity Provider, then yes, OpenID or the newer OpenID Connect support (see http://oauthssodemo.appspot.com) is the way to go.
In either case, there are other precautions you can take to make sure the email address really belongs to the user. For example, when using OpenID with Google Apps Google generally only asserts verified email addresses, and you can simply whitelist Google as a provider. If you're using the apps' version of OpenID (modified discovery protocol) then you can restrict OpenID requests to a particular domain (only make requests to that domain, an check on the response that the ID matches what was requested.)
In the case of OpenID connect, it's explicitly stated in the response whether or not it is a verified address.
Related
I have built an API to my web application so that customers can access certain functionality without going through the dashboard. I have secured it by providing an API key to each customer that identifies them and restricts the IP address from which they can connect.
I have now had a request from a customer to allow them to access this API from their Salesforce platform. I don't know much about Salesforce, and when I asked them to let me know their IP address so I could create their API key, all they could give me was the list of reserved IP addresses published by Salesforce. This IP space is huge (millions), covering all of Salesforce, meaning that if someone gained access to the API key they'd be able to use it from any Salesforce account.
I have read some things about Salesforce having an OAuth service and having some kind of Application Connect service, but it mostly seems to be designed around allowing 3rd parties to connect to Salesforce - I'm getting a bit bogged down trying to determine if this is any use in my scenario (which requires authentication in the other direction).
I'd be grateful for any insight into whether there's something more specific I can do identify a particular Salesforce customer beyond simply putting dozens of CIDR blocks in my API key. I could ask my customer to identify themselves in the referer header when they call my API, for example, but of course that's trivial to spoof.
Thanks.
IPs can be spoofed too
Salesforce has a concept of "protected custom settings". You could make a "managed package" (Salesforce plugin, but you don't need to distribute it on their appexchange, Google Play/App Store equivalent), install it for the client and then enter the API key to the setting in a way that even client's sysadmins can't read it.
It'd be bit of work to set it up but might pay off if you think you'll get more customers on the platform.
How about a crude but effective iframe? or a link to your page they'd embed somewhere in their app?
Do you have just api keys? If you'd expose OAuth2 endpoint SF users could login to your app and then SF code could use access_token they got back instead of api keys. Or maybe you can protect access with certificate? Calling app would have to sign requests with a certificate. Client could upload it to their SF, you'd upload to your app...
You could demand the API calls to include the user's SF "session id" and you could use that to run some queries against source SF org. Org Id, user's login history etc things that are impossible to tweak even by sysadmins...
For authenticating end users to things like IoT services, many cloud services have a custom option: The client authenticates with the dev's own server (however the dev implements that), which in turn gets a token from the cloud service and sends that to the client for authentication with the cloud service. Amazon and Twilio are examples of this. This allows for a fully customizable auth.
If I understand correctly, Google Cloud Platform requires end users to authenticate with Google's OAuth2 service, meaning they must sign in with a Google account. I don't see any way around this, but the limitation is so severe that I wonder if I'm missing something. Is there some way I can instead authenticate users my own way?
meaning they must sign in with a Google account
That's not entirely correct, you probably overlooked this in the very doc you referenced (emphasis mine):
Firebase Authentication gives you a robust, secure authentication
system-in-a-box that helps you do sign in with any account your
users want to use. Firebase Authentication supports password
authentication in addition to federated sign in with Google, Facebook,
Twitter, and more, allowing you to easily scale your authentication
system as you grow on desktop and mobile.
So you can have your users choose their username and password or login using one of their supported 3rd party non-Google accounts.
But it will still be Google handling the authentication for you, which is good if you plan to use other GCP products/services as the authentication can be propaged.
If you want to handle the authentication yourself - nothing stops you from doing that, but it may be difficult/impossible to integrate it with other GCP products/services. The Plain OAuth 2.0 might be what you're looking for (I don't understand it enough), search for it in the Compare Auth Options guide.
I have been doing a lot of research into how to authenticate mobile apps with an API - I still feel a bit unsure about which flow & architecture would be better to use in my particular use case.
I think what's confusing me is some of the terminology used.
My use case:
An API & database on one server. Which holds the users & and the users resources.
A web app, which I have built and consumes the API. Hosted on the same server as the API. So it's dogfooding.
A web app, which I have built and consumes the API. Hosted on a different server to the API.
A mobile app, which I have built and consumes the API.
I'd like to be able to authenticate with the API using username & password.
The API will never be opened up for consumption by other 3rd party services except the web app and the mobile app.
Initially I felt like using the Resource Owner Password Credentials Grant flow would be sufficient. However in the docs it states that this flow should be used if "The client is absolutely trusted with the user credentials".
Since both my mobile & web apps will be built by me, I'm assuming they are seen as 1st party clients. Therefore am I right in thinking they are considered to be trusted with the user credentials? As I typically thought that when implementing oAuth, the idea would be to have the authentication server separate from the resource server. Which would allow you to have one authentication server for multiple APIs.
After reading this post: Why the Password Grant is not suitable for modern applications
It threw me off track a bit. But then, is this post talking about using this flow in my use case?
I was also looking at the Implicit Grant Tokens flow. However using this flow I couldn't really see how the user would enter their credentials first?
I also question if any of the oAuth flows is really needed for my use case and I should instead look at other ways of authenticating?
I'm really quite lost with this I would like some direction to go in with how to authenticate users in my particular case.
Thanks in advance!
I'll most likely be using Laravel to house my API and so I do have Passport available to me to implement oAuth
EDIT
From following this oauth article I've found that in all use cases of my app, I end at Password Credentials Grant flow. Would I be correct here?
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.
I am starting a new web project and I intend to make it API based; that is I want to build the API first, authenticated via OAuth, then build a website and possibly mobile app(s) that use the API to handle data. I also have my eye on opening up the API to the public.
Here is my issue; I am struggling to get my head around how to authenticate these 'official' apps, the ones made by me, including the main site.
In OAuth the client creates an account for each user then seeks access rights via the resource owner logging in at the main site. This obviously does not work for me because the main site and the client are the same place and it also implies my users should be creating two accounts just to use my website...
I believe twitter uses its own API to run twitter.com and I get the impression that this approach is becoming quite normal so there must be a standard approach.
I must be missing something, but what?
You are confusing the API (business logic) with the authenticaton of user identity (for example logging in), and the authorization of third party apps (OAuth).
It is correct that twitter.com uses their own API. But they don't use OAuth on their own site. When you're on twitter.com, their APIs are available to themselves over cookie authentication. To put it simply: you're logged in.
Once you move away from twitter.com you have to use OAuth. Now an application is using the API on behalf of a user.
To sum up. You don't specifically need OAuth for your "own" web client to use your own APIs. You need OAuth, or some other authorization mechanism, to publish your APIs and it will also come in handy for your own "official" apps.
There is really no need to distinguish your own official apps from third party apps. Not from a technological perspective anyway.
Host two versions of the "API". One mapped to the external domain api.yoursite.com and it OAuth-enabled to authenticate all requests. The other internal version is accessible only within your pool of servers, your official apps. Since only your official apps can access it in the first place, consider all requests to the internal API trusted.
If you want the same application to manage both external and internal calls, you can choose to
distinguish external and internal requests based on incoming IP addresses
implement your API to accept one of "VIP passes" or OAuth tokens for authentications. External apps use OAuth tokens to perform actions on behalf of certain users. Official apps use "VIP passes" to perform actions on behalf of any user.