How do I use Google's Identify Platform to authenticate against Cloud Endpoints? - firebase-authentication

In our organisation we use the Google Kubernetes Engine (GKE) to implement a micro-service architecture. As we are also G-Suite users, everyone in the organisation is guaranteed to have a Google account. In consequence we would like to use those accounts to manage authentication and authorization of micro services.
We have prototyped login using the angularfire2 client to authenticate against the Google Identity Platform. We also have Google Cloud Endpoints configured to control access to relevant services.
The piece we are missing is how to get from the identity in Google to an access token we can use on our services -- the access token coming back using the Firebase API has no claims in it, and the documentation on custom claims seems to make it quite clear that these go into the identity token.
My expectation would be to have JWTs with the appropriate audience (our backend), containing a sufficient set of claims to implement role based access control within the services. Ideally the infrastructure could validate a claim already -- some of our services are small enough to require only one role, which could be enforced outside the service. Or we could annotate our endpoints (Protobuf) with the required claims.
In the GCP environment, what is the standard process of creating access tokens to be used for accessing GKE services? Is there anything that supports this?

The piece we are missing is how to get from the identity in Google to
an access token we can use on our services -- the access token coming
back using the Firebase API has no claims in it, and the documentation
on custom claims seems to make it quite clear that these go into the
identity token.
Google OAuth Access Tokens do not have an identity in the sense that you want to use it. Identity is stored in the Identity Token. Add the scope "email" when authenticating the user. Google will return an ID Token. For some frameworks, you can request custom claims for the Identity Token.
In the GCP environment, what is the standard process of creating
access tokens to be used for accessing GKE services? Is there anything
that supports this?
There are two types of access excluding methods such as API keys. User Accounts and Service Accounts. Service-to-service typically uses service account Access Tokens (RBAC) or service account Identity Tokens (IBAC). In your case, you want to use Identity Platform which means User Accounts.
If I was designing this system, I would use User Accounts to authenticate with the system - Firebase is great for this purpose. I would look up what roles this identity supports/allows from my database (Firestore) and create a service account Access Token with the required scopes for GCP services. I would then use this Access Token for GCP service-to-service authorization. If I also required custom roles for my own services, I would create a custom Identity Token with my custom roles and include that as a custom HTTP header and include the Google Access Token in the standard HTTP "authorization: bearer" header. I would use the service account private key to sign my custom Identity Token or use a GCP IAM API to sign for me so that the other end can verify with the service account's public key. This method prevents data leakage at the client, no private keys are distributed, scopes/roles are not disclosed, etc.

I would suggest you follow this doc of authentication between services by using service account files.

Related

Which Authentication suits best for Azure Function app when exposing to third party

I am trying to understand which authentication suits good for Azure Function app because I have to expose function app end point to external team.
I have enable Azure AD authentication and planning to share App registration client_id and client_secret (endpoint oauth2/v2.0/token) where they will generate bearer token to Authenticate and consume my endpoint.
I was wondering if there is any other best approach of authentication than Azure-AD because I am exposing to external team.
Please assist, Thank you.
the most secure option is to request access tokens trough the Azuthorization Grant Flow with PKCE. No secret is required, however if you need to use one, we recommend using certificate credentials which are asymmetric thus the exposure of the secret is more and better controlled.
You can also, configure token and enforce additional security measures trough Conditional Access policies. With them you can configure session lifetimes, require MFA for selected or all external users that access your application, that they authenticate from a compliant device, well known IP range or location, and more.
Also, and at the PAAS level, you can Set up Azure App Service access restrictions.

Google OpenID Connect User Authorization

We have a SPA web application that supports OpenID Connect login from external Identity providers. Our application supports different user types (roles). We want to support Sign in with Google using Google Identity service (https://developers.google.com/identity/protocols/oauth2/openid-connect) but the Access Token seems to be for Google APIs only (we want to protect our own APIs). The ID Token is a JWT we can validate, but there is nothing in the claims we can use for Authorization.
Is it possible to add custom claims to the Google ID token that we can use for Authorization?
From the link above...
This document describes our OAuth 2.0 implementation for authentication, which conforms to the OpenID Connect specification, and is OpenID Certified
I guess this means they ONLY support Authentication and not Authorization? Is this true? Or is there some other Google service we need to use to get user roles (Google Cloud IAM, etc.)?
How does Google expect us to Authorize users they Authenticate?
To get control over what the tokens contains, then my recommendation is to add a separate identity provider in-between your applications and Google. In this way, your applications only need to trust your local provider and it can provide the tokens that you need and you can add additional user information/claims to the tokens.
Just like this picture tries to show:

OAuth authorization flow for private API with Microsoft AD

Our company is using Microsoft AD for user management and authentication, also the authorization is done using the AD groups/roles. In the most 3rd party applications the users can authenticate with their AD accounts.
Now we are developing new applications, which should use an internal API. Therefor we created a new enterprise app in our Microsoft tenant and defined a couple of roles.
On the client side it is the normal flow - users authenticate with their accounts and the client receives the access token it should send to the API. And here is the point where I am not sure what is the best way to implement it.
Since all the users already exist in the AD, there is no need to only use access token to get the user identifier and create/link the user in the internal database - I want to use the AD users and to be able to verify the roles and use them in the services behind the API gateway "as is". But the roles are not stored in the access token, so I assume, I have to request them from Microsoft separately. But also I do not want to request them every time a user sends a request to my API and want to rely on the token the cliends sends to me and which I can verify.
So what is the best way to implement it? Should I create a new Bearer JWT in our own auth service, containing all information I need, and provide it to the client, so that it sends it to me every time? Should client use this token for authorizing the user as well? But it also can request the IDToken from Microsoft? Would our internal token replace IDToken and Access Token? Or should we just use IDToken for requests to the API?
Creating an own token looks like an overhead to me, since we only work with AD users but I also don't want to use IDToken for authorization in the API.
In an OAuth architecture your apps (primarily APIs) accept tokens from the Authorization Server (Azure AD in your case). You then use these tokens to authorize requests for data based on Scopes and Claims. Avoid issuing your own tokens and use AS tokens consistently. It feels like you then need to deal with domain specific claims, which is tricky, and these are the main concerns:
Option 1: Custom Claims in JWT Access Tokens
This requires Azure AD to reach out to your internal API at the time of token issuance. This is the preferred option but it may not be supported - or possible - depending on the provider and hosting infrastructure.
Option 2: Custom Claims via Lookup
Here is some example C# code of mine that shows a technique where you form a custom claims principal in the target API. The extra claims are looked up (typically from a database) when the access token is first received, then cached for future requests with the same access token. It is not ideal but I have had to use it in the past due to vendor limitations.
Confidential Internet Tokens
Be careful when including claims in access tokens to not reveal sensitive data to internet clients, eg web or mobile apps. Aim to use the phantom token pattern if possible, so that you do not reveal any sensitive data. If the Authorization Server does not support issuing reference tokens, then option 2 above may be the least bad option.

Is it possible to make authorized calls to SFCC (demandware) OCAPI /shop using external customer authentication (e..g Cognito access token)?

Today, we use SFCC for e-commerce and it has also acted as our primary identity provider. We're in the process of migrating users and transitioning to use an external identity provider, Amazon Cognito.
After the migration, our hope was that we would be able to perform authentication using the external idp (Cognito) and use the issued Cognito 'Bearer' tokens to call the shop API.
Is this possible? Or, does the shop API require a JWT issued by SFCC?
I've not done it before, but there's a relatively new way to authenticate customers from a 'trusted system'. You can find more information about that here: https://documentation.b2c.commercecloud.salesforce.com/DOC2/index.jsp?topic=%2Fcom.demandware.dochelp%2FOCAPI%2Fcurrent%2Fusage%2FJWT.html
If your client application manages your customer credentials, it can obtain a JWT for a registered customer using the /customers/auth/trustedsystem resource. Because this API uses an OAuth token to identify the client application, we strongly recommend that you only use it in a system-to-system integration, where the client application keeps its own OAuth token secret.
After you are able to authenticate the customer you could use the Session Bridge functionality to convert that JWT to a session cookie.
Good luck!

restful api authentication confusion with oauth2

I did some investigation about restful api authentication. Most people pointed to Oauth2 for restful api authentication. I looked into some of resouces, especially this link https://developers.google.com/accounts/docs/OAuth2.
It seems to me Oauth2 is for a third party app to access users' data in google/facebook(or other data provider).
Our problem is that we own the data, we don't need to access our client's any third party data and our clients don't have to any third party data. We want to protect our api with some sort of authentication.
For our case what is the convenient technologies for our restful api authentication ? We will expose our api like this
https://ourdomain.com/api/<endpoint>
Our clients can access a website first to register https://ourdomain.com and they should be able to get clientId and clientKey from our website for accessing apis. Our clients should be able to consume through some sort of authentication
In oAuth 2.0, there are several types of grant types. A grant type is just a way to exchange some sort of credentials for an access token. Typically oAuth refers to 3rd party usage with a Authorization Code Grant. This means redirecting the user to the resource owner's website for authentication, which will return back an Authorization Code.
This clearly doesn't make sense for 1st party oAuth use, since you ARE the resource owner. oAuth 2.0 has considered this and included the Resource Owner Password Credentials Grant for this purpose. In this case, you can exchange a username and password for an access token at the first party level.
See https://www.rfc-editor.org/rfc/rfc6749#section-4.3 for more details.
If I understand correctly, what you need it similar to OAuth in a way that you do the exact same thing minus granting a 3rd party app access to a user's resources.
In OAuth, there is a central system that manages authentication and authorization by checking an app's credentials + user's credentials and dishing out authorization tokens. There are multiple endpoints that will accept these authorization tokens.
The tokens are basically encrypted strings that contain info about the user's credentials and some other info that might be needed by your app.
What you need (i believe) is a similar authentication endpoint, that the client hits with its credentials and gets a token.
So,
i) Create a registration form/console where a client can register and get his credentials. Have a look at this.
ii) Define a HTTP endpoint where the user exchanges his credentials for an access token + refresh token.
iii) The client can hit the resource endpoint with the access tokens to make authenticated calls to any of your endpoint.
iv) At the back-end you'd need a common service that verifies the tokens and extracts info from it.
PS - This is just a minimal system, there would be a lot of security considerations like what if some unauthorized app gets access to some client's access tokens.
You can find much information about CSRF attacks, noonces, timestamps and other methods of mitigating security concerns.
Just to be clear with the original question:
OAuth2 needs at least a client and a server
OP was wondering how to secure a REST API, and why everyone is talking about third party authentication providers (Google, Facebook, ...)
There are 2 different needs here:
1 - Being able to secure a personal API (ourdomain.com)
Client Server
Consumers <----> Your API
2 - Being able to consume a public API (For example getting a user's Google contact list)
Client Server
You <----> Google APIs
OP actually needs the 1st: implement an OAuth2 server in front of its own API.
There are many existing implementations for all languages/frameworks on Github
Finally, here is one nice Oauth2 technical explanation, and I'm shamelessly taking one of its schemas here:
No I'm not working at Google, I'm just taking Google as a public API supplier example.