Google Idenity Aware Proxy Authenticate with API on SPA - google-iap

I'm curious what is the "best practice" for authenticating against a restful-api that is protected by Google IAP.
Allow me to break it down step by step to elucidate what I am trying to achieve:
Go to my dev environment's url: dev.blah.com. Here, I am prompted by IAP to log-in. I log in. I now have access to my SPA.
I am browsing my SPA. But! I'm unable to talk to my API, because it is ALSO protected by IAP.
I've read that I can do programmatic authentication in the documentation but I'm unsure if my particular use case is suited for programmatic authentication, or if it will even be SECURE.
So, am I correct in that I will have to implement a client-side programmatic-authentication workflow in order to access my API?
Or is there an alternative way to say "Once I'm authenticated to access THIS IAP-protected resource, i can log into these other resources as well." I cannot simply copy the token because it is http-only and the cookie is restricted to my current domain.
Some additional information:
My services are running in a Google Kubernetes Engine cluster and have automatically created load balancers based off of ingress objects I declare.
Each IAP-protected environment gets it's own OAuth credentials, and I configure the load-balancers to use IAP using: gcloud compute backend-services update [backend-service] --global --iap=enabled,oauth2-client-id=[the_id],oauth2-client-secret=[the_secret]

let me make sure I understand what you're trying to do. It sounds like you want to call your API from JavaScript inside the web browser, is that correct?
If so, and:
All backend services are configured to use the same OAuth client ID.
The API and the SPA are serving off the same domain.
then I think things will just work, because the JavaScript-generated HTTP requests will be sent with the IAP session cookie. ... Which must not be your setup, or things would just be working which clearly they aren't. :>
If you're not able to arrange for your API calls to use the IAP session cookie generated when you authenticate to the SPA, this will be tricky. You wouldn't want to use service account authentication from the browser, since that would give all end-users access to the service account.
Hm, it looks like there is a way to do Google OAuth from JavaScript: https://developers.google.com/api-client-library/javascript/features/authentication -- I haven't tried it, but if you're able to get that working, you ought to be able to use a flow like https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_desktop_app . If you want to go that route, let me know how it goes and I'd love to help you get unstuck and then get that approach added to our documentation!
--Matthew, Google Cloud IAP engineering

Related

How to share a login between two sites without passing tokens around (Web-SSO)

I have two sites, one of which is essentially embedded into the other, although they have to be loaded from different URLs. They both access the same backend API. I want the user to log in once and be able to access the API in the embedded site without having to log in again. Essentially, I guess this would be Web-SSO. To complicate things even further, the outer site is a legacy PHP site with a backend server, the inner is a single-page react app.
I'm looking for a way to pass the login from the outer site to the inner site, without actually passing a login token around e.g. as an URL parameter, which would probably not be safe.
Essentially what I'm looking for is something Site A can safely give to site B, that will tell the authrisation server "Site A is authorized, and Site A trusts Site B, so it's OK to give Site B a token too"
Does such a mechanism exist? Some people have suggested OAuth2 and OpenID to me, but in all the documentation I've read, I haven't found any description of this use case. To me, this looks like OAuth2 in reverse. All examples I have seen concern the use case "Site A wants to access Service X, so it needs to authenticate with the Auth server Y, to get a token that will let it access the service". A second site wasn't part of the picture in any of the examples I could find.
Is OAuth2 even the right technology for this, or do I need something else entirely? How does one implement this use case?
If I understand correctly, you just want/need SSO. Since if a user logged in in site A (or any *.domain.com or *.com that is registered as a "safe" application) it will also be logged into site B.
Essentially how this works is when the user is logged in there will be a cookie stored on this website and (not sure) also on the API login website. Then whenever the user tries to enter website B e.g. the application should check for a cookie on site B. If there isn't any cookie it will look for a cookie on the API login website. If there is it will automatically login (without credentials). This is basicly what you say.
Site A can safely give to site B, that will tell the authrisation
server "Site A is authorized, and Site A trusts Site B, so it's OK to
give Site B a token too"
This could be achieved by using a third party like Auth0. Im currently trying to implement this in Symfony. So far not much success but since I searched alot for other SSO providers I think this is the best shot. Also for your needs I belive it will work good enough.
Another option:
Create a API authentication server yourself. This way you have full control over it. But you need to manage it all yourself, also the security. There are probably packages that help you alot but still, you need to figure out alot by yourself.
My advice is to check out Auth0 by just creating a free account. See what it can offer and try some things out.

Setting up OIDC via Auth0 for a web site that is hosted on customer networks

As part of a process to update/secure/centralize our auth and licensing process, we are looking at using OIDC via Auth0. Part of our package is a web site that is typically hosted on customer networks. We are trying to figure out the appropriate flow to use in this situation. It seems like we would need to set up an appropriate Callback URL for the applications which would need to point at the customer hosted instances.
Is there more appropriate flow that doesn't require that callback? What is the appropriate way to handle that?
Sadly you will always need a Callback URL when it comes to the authentication workflow that way you know where to redirect users after login. I have attached documentation supporting this process. I hope this helps you in your adventure!
https://auth0.com/docs/users/guides/redirect-users-after-login

Using OAuth2 to permit users to authorize as a global user

Apologies for the oddly worded title, however I could not come up with a better one.
My application should be able to perform a limited set of actions on an Enterprise Google Apps system. Users submit requests to the application, the application interprets these requests and then makes requests to Google resources as necessary.The point is that users, who normally do not have permissions to access/modify the google apps resources, will be able to use this application to do so in the limited ways that it allows.
My problem lies in the apparent fact that the OAuth2.0 authorization flow seems designed to allow third party client applications to authorize themselves as the user and access/modify the user's google resources, rather than a global administrator's. In other words, a normal API key type deal. Unfortunately it seems that Google's AdminSDK will only work with OAuth2 authorization.
Is there a way to use Google's AdminSDK API with OAuth2 (permanent access token, maybe? API key?) to do what I want? Or is there a different API I should be trying? The now-deprecated Provisioning API seemed to be able to do this.
I feel like there should be a way for the application to just pull something out of a secrets.json or secrets.yml, include that in the API authorization request and have Google servers recognize and grant access to the application without the user ever needing to see what's going on.
For the record I'm using Ruby on Rails, though I don't think that affects the question very much.

Client-server user authentication

UPDATE: I failed to mention earlier that we want solution that will be flexible with authenticating users from within our databases or by asking other servers to tell us if the user is authenticated. It is also worth mentioning that these other servers are not under our control so we can't enforce a specific user model.
I had a long and hard read on OAuth and OpenID but they are both not a suitable solution for our situation and will make the process harder to the user. This is something that has been solved a thousand times, yet I cannot find the solution.
What we are looking for is a framework that can be used in a REST services server to authenticate users (no third-party clients involved) with their username and password.
The solution must not pass the username and password except the first time on login and use tokens for further authentication. Even though OAuth does use tokens, it is designed to allow third-party clients access to the service-providers resources. That is not the case here, the services are for our own application only, the only thing needed is user authentication.
What do you guys think is the most appropriate solution?
Configuration:
-Spring server that provides RESTful services with our thinking going towards using Spring Security with some user management and token management framework.
-iOS Device that will be making HTTPS calls to the server.
What we ultimately want is to have the device send a login request and receive a token if the login was successful, later on make requests using that token. Just like Facebook, excluding third-party involvement.
Is there something that is ready to be configured in our server? Or should we consider building our own token management, comparison and generation software?
Is using Spring-Security with an iOS application without involving storing cookies or redirecting to pages possible?
OpenStack offers as part of it's many projects related to open source cloud... the project Keystone. Which does this pretty much exactly what you want.
You might want to check it out here:
http://docs.openstack.org/developer/keystone/

Best authentication method to grant API access to Rails app

I would like to offer authenticated API access to my web app. The consumers of such a service are typically other web sites/services.
What would be the best method of authenticating these users? OAuth, openID, http authentication?
As so much in our line of work, the answer to "which is best?" is "it depends." :)
HTTP Authentication - If you're already letting clients log in to your service via an ID and password, you'll probably only have to do minimal work to get this to play nicely with your API. If your API is basically mono-purpose and doesn't require detailed permissions, you can get something working fairly quickly here.
API Token - If you want clients to be able to authenticate easily without providing a password (think companies that build a service that interacts with your API; maybe the IT dept. doesn't want the dev. team knowing the passwords; etc.), then attaching a random API token à la GitHub to the user account is probably the quickest way to go. As a bonus, you can supply a method for regenerating the API token without having to change the account password.
OAuth - If you have multiple permissions or want finer-grained control over how and when a client can access your API, OAuth is a pretty good bet (OAuth2 is much easier to work with, IMO, and supports multiple methods of obtaining an access token). Furthermore, many languages have libraries, gems, etc. that will allow them to simplify the OAuth workflow.
I would say the "best" method is oAuth. It's more flexible and it can be application independant for further uses .
I am using oAuth to authenticate my clients (applications).
;)

Resources