Replacing Google Sign-In for Websites with Cloud Identity-Aware Proxy - metabase

There's an open feature request for Metabase to support IAP. I took a stab at it, and have a Clojure implementation of the steps detailed in Securing your app with signed headers (i.e. verify token header, verify token payload, retrieve user identity).
But this question isn't necessarily specific to Metabase. The general idea is to replace Google Sign-In and only use only IAP signed headers for authentication and user creation in an application on Google App Engine (specifically, GAE flex environment).
The "problem" is that the user identity information from the IAP token looks like: {"email":"alice#example.com","sub":"accounts.google.com:118133858486581853996"}. I also came across Using special URLs, but this returns something like: {"email":"accounts.google.com:USER_EMAIL","sub":"accounts.google.com:118133858486581853996"}.
With a Google Sign-In token, I can obtain values for given_name and family_name along with email, which means I can fetch-or-create a valid Metabase user. Is there a way to get the first and last name via the JWT sub, (i.e. accounts.google.com:118133858486581853996)?

Hm, if they have a public profile you can pass the number after "accounts.google.com:" to https://developers.google.com/+/web/api/rest/latest/people/get . Unfortunately, you won't be able to authenticate to that API as the user, since IAP doesn't currently provide a way to call let users delegate access to call Google APIs. (You'll have to use a service account to call that API.)
The other solution would be, if IAP provided a way to a) specify additional scopes in its OAuth request to Google, and if it then b) passed additional claims from the OIDC token into the IAP JWT, you'd be able to configure IAP to request the "profile" scope. However, IAP currently only requests the "email" and "openid" scopes, and doesn't have a mechanism for specifying additional scopes.
-- Matthew, Google Cloud IAP engineering

Related

If anyone take my Google Sign in token, can he or she sign in via that access token?

I am learning react-js development, from this course I learned that I can use Firebase and Google sign as a third part storage service and sign in verification service, I draw a sign in steps with drawio diagram, as diagram below if someone take my (2) Google verification token or (6) Firebase access token can he or she sign in my website on his machine by that two tokens before expired ?
clarification about google token or firebase token security level.
That's a pretty standard OAuth flow. Firebase JS SDK does the same under the hood when you call signInWithPopup():
Getting user's access token after user's approval
Signing in with the response (see sign in with OAuth credential)
Yes, if I somehow get your Google Access Token (2), I can use it to access your account's data (for the scopes it has access to). Similarly, Firebase tokens are generally used as a Bearer token that means anyone in possession of the token gets access to the resources.
But chances of someone getting these tokens are slim to none (unless they have physical access to user's computer). As long as users do not share these tokens or any malicious script tries to read them, this flow has no issues.

Firebase Appcheck and RecaptchaV3 Provider

I'm wondering if someone can explain the overlap between Firebase AppCheck and Recaptchav3. I have a public web application with AppCheck enabled and configured to use the Recaptchav3 provider. An integral part of using Recaptcha however is verifying the client's score to determine whether or not to deny the request. AppCheck does it's job in my Firebase function by providing attestation based on referrer, however, I haven't found a way to retrieve the Recaptcha score.
I've tried retrieving the AppCheck token from the X-Firebase-AppCheck header and submitting it to the Recaptcha service for verification, but that returns an invalid user response error.
So my question is: is it possible to retrieve the Recaptcha score from the callable function context? If not, how is this case normally addressed?
I've manually included the Recaptcha script and retrieved the token on the client side which works, but that amounts to Recaptcha being added twice (first with AppCheck and second from a manual inclusion), which doesn't feel right.
I've spoken to Firebase support and it seems that it is not possible to retrieve the Recaptchav3 score from AppCheck. So the only solution is to retrieve it on the client-side as you would in a typical Recaptcha config, and submit it along with the request to your backend. The process to verify the Recaptcha token and retrieve the score once received at the backend remains the same.
So at the moment, the only value AppCheck on the web provides is automatic referrer verification.

Azure AD OAuth generates token for audience without permission

Despite reading multiple articles and tutorials at Microsoft.com, I am having an issue to understand how to define permissions between APIs using app registrations/OAuth2 in Azure AD. To exemplify, I have set up 2 simple app registrations in Azure AD, one for a back end API (lets say client ID A) and another for a front end or another API (client ID B). Then, I set up a basic .NET Core API with default (template) authentication (Options = tenant, client ID, etc) and the default weather forecast endpoint.
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
services.AddControllers();
Right now, I am able to get a token from https://login.microsoftonline.com/<tenant>/oauth2/token with Client ID = B and resource = Client ID A, and when I send this token(with 'aud = A') to the API it accepts it.
Why is the token generated successfully, even though I have not set up any relationship between App Registrations A & B? The API Permissions tab in Azure AD is empty in both registrations - I thought AAD would reject the request stating that App B does not have access to App A. Or am I entirely responsible to validate audience claims via code on my app?
It is possible in Azure AD to acquire an access token through client credentials flow to an application that the client app has no permissions on.
This may be to enable some scenarios where the target API handles the whole authorization, but I am not sure.
I wrote an article some time ago on the need to check permissions always: https://joonasw.net/view/always-check-token-permissions-in-aad-protected-api.
I also wrote a follow-up after Microsoft addressed the cross-tenant ability to get access tokens: https://joonasw.net/view/cross-tenant-token-attacks-now-harder-in-azure-ad.
Because a client can get a valid access token without permission assignments,
authorization is crucial on your API side.
At our company we have a default authorization policy that checks every request that it contains either a valid delegated permission/scope or a valid application permission/app role.
That gives us a baseline that already protects the API from tokens like that.
It is usually not the only authorization applied.
In case delegated permissions are supported, you need to check that the user also has access to the thing they are trying to do.
Delegated/app permissions after all only say what the client app can do.

Sign out user via REST HTTP API

I can sign in users to Firebase using this HTTP API:
How do I sign out users, so that the Firebase idToken and refreshToken can no longer be used?
Also, how long is the refreshToken valid for?
If my user does not use my app for weeks, can I still use the refreshToken or will I need to get a fresh Google Sign In idToken and exchange it for a Firebase (idToken, refreshToken) pair via the /identitytoolkit/v3/relyingparty/verifyAssertion API?
I don't believe there is a sign out endpoint. You could try doing a redirect to https://accounts.google.com/Logout but I suspect that is signing out from all Google services which might not be a great idea.
The whole point of Refresh Tokens is that they can be used to access resources whether or not the user is present and signed in, so your comment "How do I sign out users, so that the Firebase idToken and refreshToken can no longer be used" is an oxymoron.
A Refresh Token is theoretically valid until a user specifically revokes it, but your app should code for the possibility that Google has expired it.
The client cannot directly revoke the ID token via the REST API, but both the Firebase Auth client SDKs (ex: Android) and the Auth Admin SDK do support it. So if your client platform isn't supported, but you are able to create a small server implementation (maybe through Firebase/Cloud Functions), you can create an HTTP endpoint that triggers ID token revocation.

How do I structure authentication with a social IdP?

My system works as follows;
I have an ASP.Net RESTful API server, which contains a user database.
I also have a Xamarin.Forms application, with a registration and login page.
What I want is to have the ability to authenticate a login using a social IdP, and then, if that user has not been logged in before, register that user in my local database.
I have been reading up on how to implement OAuth 2.0 with OpenID Connect to authenticate my users with a social IdP, however, I cannot seem to wrap my head arround it. From what I've read, I shouldn't use an Access token for authentication, since that i what the ID token is for, however, I have also read that the only intended purpose for an ID token, is the client.
My problem then is, how can I make sure that calls made to my ASP.Net server, has been made by "real person", and how do I determine who makes the call?
Access token will be used determine whether the client application was authorized by a user to access a resource. The concept of ID token comes from OpenID Connect. Main purpose of the ID token is to authenticate the user to the client application (i.e. letting the client application know that the person who authorized the access is a valid person).
To do this, you have to validate the ID token. This can be done using third party libraries such as nimbusds or auth0. You can validate the signature of the token verify the integrity of the token and check the claims included in the token (by comparing them with expected values) to verify the user details. Also, you can add custom claims (any claim that is specific for your application/implementation) to the tokens through your identity provider so that you'll be able to validate those particular claims in order to verify the user.

Resources