How to select and work with a particular Provider (OIDC provider) added on Google Could - Identity platform by using server side java code - google-cloud-platform

I have added these 2 identity providers (refer attached images) to Google Cloud -->Identity Platform
Email/Password
OIDC Connect (oidc provider)
Now if you see there is a User section as well under Identity Platform
So I have added some random users which are non gmail users (refer image), like xyz#abc.com, which I want to authenticate with the help of Google Cloud (it when this user comes to login, I will hit API endpoint /login and in login server side code, I will redirect to Google Cloud to Authenticate this user using OIDC Authorization flow)
I need Java code to :
Using some java code, First choose the provider as OIDC provider (oidc-auth-provider).
Make call to Google Cloud which should use this Provider (oidc-auth-provider)
This oidc-auth-provider should look up the users which I have created under Users section (refer image)
Google Cloud after verifying user exist, should send back with Auth Code
using Auth Code I will call back to Google and get ID token/JWT token
I was referring to this link :
https://cloud.google.com/identity-platform/docs/web/oidc
If you search "Signing in users with OAuth" this section on page, that is what exactly I am looking for, but the problem is it has given a UI code example using Firebase API example, to create OAuthProvider instance (which will choose provider), but I need server side code example instead, I am not sure if I can use this Firebase API on server side java code for a web application? Any suggestion that how can I do similar things from a server side Java code?
added Providers under Identity-platform
Added users manually which I wanted to authenticate

Related

How to send requests to Cloud Run only from the app?

Subscription based iOS app I'm building uses Cloud Run service invoked via HTTPS request.
How can I make sure that the request can only be invoked by app owners(from the app)?
I've looked at Google Sign-In authentication, but I don't think it is applicable in my case as only those subscribed to the app should have the access, not just those with Gmail account.
I think without a Google Sign-in involved, your question has nothing to do with Cloud Run and can be generalized as:
How to send requests to to a backend app only from its mobile app?
So I'll answer that.
You'll find out that you need some form of "authentication" to prove that you're on a mobile app as a "user". To achieve that, you need some form of sign-in.
You may try to ship a secret (like a token or private key) in the application and use that to authenticate, but this will be susceptible to:
exfiltration of the private they from the application bundle through reverse engineering
applying a man-in-the-middle attack to the HTTPS request (and therefore the token) by trusting a root CA on the device and using e.g. mitmproxy to decrypt the request as plaintext.
In reality, there's no way to fully secure iOS/Android <=> backend communication that. Even the largest apps like Twitter, Instagram etc have their APIs reverse engineered all the time and invoked from non iOS/Android clients as the requests can be spoofed.
If you want to authenticate your existing users, you should figure out how these people login to your app. This could be simple username:password in Authentication: Basic [...] header, or something more complicated like OAuth2 which is what apps like Facebook, Twitter implement under the covers for their mobile apps.
Then you would validate that Authentication header in your Cloud Run application code yourself.
So again, I don't think this is a problem specific to Cloud Run, or any cloud provider.
If your goal is for your API to only be called when your users are authenticated in your app, I would recommend implementing one of the two solutions described on this page:
Using Google Sign-in or Firebase Authentication

In GoogleAppEngine oauth flow how to get Web App credentials

I have a web app in Google App Engine (with Flask) that needs to ask the user for permissions.
I followed this explanation and it got me working great.
But how do I get the secret_file (or client_config) credentials?
All examples I saw used a local file - but that is not production safe! Is there any way to get it from the application credentials?
I also tried using oauth2client.client.GoogleCredentials.get_application_default() but that seems to be a service account which I can't use.
Creation of web app authorization credentials is discussed here.
Once you are done with the form, client_secret.json file will be generated and is downloadable via the API Console.
There will be a 'Download JSON' button at the right of the OAuth Client credential you created and at the upper part of the page when you click on the Client ID.
From this documentation, it is explained how to construct the authorization request using google-auth-oauthlib.flow module.
In Python, call the from_client_secrets_file method to retrieve the
client ID from a client_secret.json file. (You can also use the
from_client_config method, which passes the client configuration as it
originally appeared in a client secrets file but doesn't access the
file itself.)

Bluemix, SSO: Calling REST service from mobile app (public client, native application)

I have a Bluemix web application (Liberty for Java), which implements some web services. These web services should be called from a mobile application (Android). I have now secured this web application by binding it to the Bluemix Single Sign On service (SSO) with a cloud directory created in the SSO service. Using the web app from a web browser works fine; but, I have problems obtaining an access token from the SSO service, which would allow the mobile application to invoke the services.
From the OAuth2 specification (IETF RFC 6749), I figured that the appropriate way of doing this would be the "native application" profile with a "public client" (as specified in Clause 2.1 of the OAuth2 Spec) using the "password" grant type (OAuth2 spec, Clause 4.3 "Resource Owner Password Credentials Grant").
I used the Spring for Android framework for this purpose, and code for this would look like this:
ResourceOwnerPasswordResourceDetails resourceDetails =
new ResourceOwnerPasswordResourceDetails();
resourceDetails.setId("dtu-se2-e15-cloud-directory");
resourceDetails.setAccessTokenUri(APP_SSO_API_ACCESS_TOKEN_URI);
resourceDetails.setClientId(APP_SSO_API_CLIENT_ID);
resourceDetails.setClientSecret(APP_SSO_API_CLIENT_SECRET);
resourceDetails.setGrantType("password");
resourceDetails.setScope(Arrays.asList(SCOPE));
resourceDetails.setUsername(USERNAME);
resourceDetails.setPassword(PASSWORD);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
UserPosition newPosition = restTemplate.postForObject(
POST_POSITION_SERVICE_URI, position, UserPosition.class);
But, I don't think that this code matters, and ultimately made my experiments with obtaining access tokens directly with curl:
Actually, I tried using two different clients with different OAuth2 token endpoints:
I created a client (and client credentials) in the Cloud directory, that I had created in the Bluemix SSO service. And I tried the OAuth2 Token Endpoint URI and the created client credentials. But it appears that this endpoint does not support the grant type "password" at all. It appears that this client is not considered a public client by the endpoint.
I also tried the credentials and OAuth Token Endpoint URI for the Web application itself (which I looked up in the VCAP_SERVICES environment variable). This end point seems to support the grant type "password"; but all variants of requests I could think of, kept responding: invalid_resource_owner_credential.
As I said, I used curl to try out many different variations of requests to these
token endpoints:
used the token endpoint URI of both the SSO services with the web app credentials
as well as the one created in the cloud directory API Access
tried GET and POST (did not make any difference)
tried Content-Type: application/x-www-form-urlencoded and
Content-Type: application/json (both of them seemed to work with the same effect)
providing the client_id only (which always was unsuccessful)
providing the client credentials in the body or parameters, as well as
authenication information in the header (actually, I do not like the idea
of providing the client secret to the Android app, but I tried that too);
as user name, I tried the name as I had created it in the web browser redirection
when registering a new user; but I also tried the user name which the Principal of
the security context of a request would provide (when successfully invoking
a service from a web browser with the user logged in); I even tried the principal's
accessId (non of these worked, I always got: invalid_resource_owner_credential)
used different scopes, and none at all
None of the above (and different combinations of that) would result in a successful
response and an access token for the user. The "best" I could get was a response
invalid_resource_owner_credential (making me believe that at least the client was
accepted in some situations).
Unfortunately, I did not find many things that could be configured concerning client
access (and public clients, in particular), and I did not find much documentation on
which subset of the OAuth2 protocol (grant types and profiles) is supported by the
Bluemix SSO service and the attached cloud directory.
Can anyone could tell me how to authenticate with a Bluemix web application
(Liberty for Java) from a mobile app (Android) as a public client or how to set
up the Bluemix web app and the SSO service to which it is bound so that this is
possible. In case it would matter, I am working with Bluemix in the "US South"
region and under an IBM Academic Initiative membership account for Bluemix.
I would prefer a solution, where the mobile app would not need to know the client
secret, but if this is the only way to make this work for now, adding the client
credentials to the mobile app would be OK.
I would appreciate any help with this problem, thanks in advance,
Ekkart
Bluemix has a mobile-specific service called Mobile Client Access that could help to facilitate security for your mobile app. To read about it, log into Bluemix and look for it under the Mobile category. To ask questions about it here, use or search using the [bluemix-mobile-services] tag.

Accessing a Google Account authenticated Web Service hosted on App Engine without browser login

I have various RESTful Web Servicesin App Engine, which are secured Google Account authentication:
<security-constraint>
<web-resource-collection>
<web-resource-name>Authentication required</web-resource-name>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
Upon hitting these Web Services via a browser client, I'm redirected to the Google Accounts login screen where I authenticate myself first before proceeding with the REST call.
However I now need to run these web service via a command line scripts as part of automated IC run. Therefore I do not want to be prompted for a browser login every time. Preferably I would like to put the Google username and password in a encrypted file on the IC server and let it call the Web Services without any human intervention. As far as I can see there are several options:
manually logging in via the browser and then saving the access token to be used in the command line script. However when the token expire I would have issues.
obtain a access token via Service Account p12 authentication. This seems to only work for accessing Google APIs such as BigQuery and Cloud Storage, not your own code.
wrap my Web Service within a Remote API which I have yet to experiment with.
Based on my current understanding, it seems there is no way for a Google Account authenticated custom written Web Service to be accessed by a non-human user. Is this correct?
Since you are interested in interacting with RESTful web-services programmatically (without human intervention), we are essentially talking about securing a REST API.
There is a plethora of resources on this matter throughout the internet but the gist of it is:
you should use SSL and sessions or OAuth to secure your endpoints.
Depending on how far you are in the current project, you could consider making use of Cloud Endpoints, there you'll have the option to use OAuth2 (and have DDoS protection), as well.
Hope this helps.
I managed to get this to work in the end by:
Switching off the web.xml security-constraint so that the API doesn't redirect to Google Login.
Modifying my API to take in a Oauth2 token in the Authorization header instead.
Validating the token based on the code sample here: https://github.com/googleplus/gplus-verifytoken-java
I didn't go with Cloud Endpoints, but Jersey + Dropwizard components instead. Dropwizard has built in Oauth2Provider which I simply implemented a Authenticator class and it works.

Does Google Apps Email Migration API v2 support 2 legged oAuth1?

Does the Google Apps Email Migration API v2 support 2 legged oAuth1?
I've looked at this answer, but I believe it refers to the older version of the Email Migration API: Does Google Apps Email Migration API support 2 legged oAuth?
I have been able to authenticate an Email Migration API request using OAuth1 w/ tokens, but all of my 2 legged OAuth 1 attempts have failed. I have tried including xoauth_requestor_id and it has not had an effect.
There is some hinting in the docs that OAuth1 w/ tokens may be required, but I was hoping to confirm that that is the case.
For example the docs say: "If your application has certain unusual authorization requirements, such as logging in at the same time as requesting data access (hybrid) or domain-wide delegation of authority (2LO), then you cannot currently use OAuth 2.0 tokens. In such cases, you must instead use OAuth 1.0 tokens and an API key."
It seems clear there that "tokens" are referenced, however the word "token" is also used to describe the Authorization request header, so it is less clear that this means OAuth1 request tokens.
Any help is greatly appreciated. Thanks!
The section you are referring to doesn't seem up to date. You can have domain-wide delegation of authority using OAuth 2.0. It's called Service Account. Once authenticated, you do exactly the same that you used to do with 2-legged OAuth 1.0.
Here are the steps you need to get started:
Go to Google Developer Console
Create a project if you don't already have one
Go to APIs & auth --> APIs and activate the Admin SDK
Go to APIs & auth --> Credentials and click CREATE NEW CLIENT ID
Select Service Account and click Create Client ID
Download the p12 private key file (and keep it safe !)
Go to your Google Apps Admin Panel
Go to Security --> Advanced Settings --> Manage OAuth Client Access (Direct URL: https://admin.google.com/AdminHome?#OGX:ManageOauthClients)
Enter the Client Id you just created along with the scopes you'll need, separated with commas (In your case, https://www.googleapis.com/auth/email.migration)
Go to your favorite language client library documentation and find how to authenticate using the private key file you downloaded earlier and also impersonate your domain users.
Hope that helps.