How to Authenticate an External Publisher in Google Pub/Sub? - google-cloud-platform

I am trying to obtain data from a web service (publisher).
The web service lets me send the data (message) to any url through a webhook. My plan is to send it to a Google Pub/Sub topic.
However, Google Pub/Sub is not recognizing this third-party web service. It is returning a http 401 response code, meaning that the web service is not authenticated.
My question is, How can I authenticate it?

Authentication for requests made to Google Cloud Pub/Sub or any other of the Google Cloud Platform services can be accomplished in a couple of different ways. In your case, where you want to make a direct request via the REST API, you'll need to create a service account and authenticate via OAuth 2.0. The Using OAuth 2.0 for Server to Server Applications guide details the process. If the web service you are using supports OAuth 2.0 authentication for requests it makes, then you should basically be set. If it does not, then you will have to take care of acquiring access tokens (and acquiring new ones when they expire) manually.

Related

Does Google Cloud API support MFA/2VS authentication?

I wanted to know if GCP supports multi-factor authentication (MFA) or 2-Step Verification (2SV) for cloud API calls.
From this link: https://cloud.google.com/docs/authentication, I read the following:
"Google Cloud APIs only accept requests from registered applications, which are uniquely identifiable applications that present a credential at the time of the request. Requests from anonymous applications are rejected.
Application credentials provide the required information about the caller making a request to a Google Cloud API. Valid credential types include API keys, OAuth 2.0 client credentials, or service account keys."
However, it does not specify if I can use these factors simultaneously.
Thanks in advance,
Vijay

How can my cloud run service call other cloud run services?

I have a service listening on 'https://myapp.a.run.app/dosomething', but I want to leverage the scalability features of Cloud Run, so in the controller for 'dosomething', I send off 10 requests to 'https://myapp.a.run.app/smalltask'; with my app configured to allow servicing of only one request per instance, I expect 10 instances to spin up, all do their smalltask, and return (all within the timeout period).
But I don't know how to properly authenticate the request, so those 10 requests all result in 403's. For Cloud Run services, I manually pass in a bearer token with the initial request, though I expect to add some api proxy at some point. But without said API proxy, what's the right way to send the request such that it is accepted? The app is running as a user that does have permissions to access the endpoint.
Authenticating service-to-service
If your architecture is using multiple services, these services will likely need to communicate with each other.
You can use synchronous or asynchronous service-to-service communication:
For asynchronous communication, use
Cloud Tasks for one to one asynchronous communication
Pub/Sub for one to many asynchronous communication
Cloud Scheduler for regularly scheduled asynchronous communication.
Cloud Workflows for orchestration services.
For synchronous communication
One service invokes another one over HTTP using its endpoint URL. In this use case, it's a good idea to ensure that each service is only able to make requests to specific services. For instance, if you have a login service, it should be able to access the user-profiles service, but it probably shouldn't be able to access the search service.
First, you'll need to configure the receiving service to accept requests from the calling service:
Grant the Cloud Run Invoker (roles/run.invoker) role to the calling service identity on the receiving service. By default, this identity is PROJECT_NUMBER-compute#developer.gserviceaccount.com.
In the calling service, you'll need to:
Create a Google-signed OAuth ID token with the audience (aud) set to the URL of the receiving service. This value must contain the schema prefix (http:// or https://) and custom domains are currently not supported for the aud value.
Include the ID token in an Authorization: Bearer ID_TOKEN header. You can get this token from the metadata server, while the container is running on Cloud Run (fully managed). If the application is running outside Google Cloud, you can generate an ID token from a service account key file.
For a full guide and examples in Node/Python/Go/Java and others see: Authenticating service-to-service

How to pass dynamic Google Cloud API Key to client side from server?

Currently, I am testing Google Cloud's Speech API and wondering how to pass dynamic Google Cloud API key to client app from server.
The speech function will be on client's app (React Native). Before every request to Google Cloud API or session, I am thinking to generate API key dynamically from server side (Nodejs) with a short lifetime and pass to client side. Only then, clients can use the Google service.
The main concern is that I do not want to embed Google Cloud API key on client app and I want to have control on which client can / cannot use the service. Is there a way to dynamically generate API keys on server side with short lifetime and pass to client? Thanks.
Update:
I was checking https://github.com/GoogleCloudPlatform/android-docs-samples/tree/master/speech/Speech and found the suggestion:
This Android app uses JSON credential file locally stored in the resources. You should not do this in your production app. Instead, you should set up your own backend server that authenticates app users. The server should delegate API calls from your client app. This way, you can enforce usage quota per user. Alternatively, you should get the access token on the server side, and supply client app with it. The access token will expire in a short while.
This is exactly what I want to do but can anyone suggest how can I achieve this? Thanks.
I am trying to find out how to get the API key for Step 2 on server backend side.
Never store credentials in users' browsers, luckily you are trying to adhere to this principle!
A setup that might be useful here has the following components:
Use an authentication mechanism in your client-side app, by means of an identity provider. You could use Okta, Auth0, Cognito, or any other authentication provider which supports Oauth2.
Use the same authentication provider to secure a custom-build endpoint, which could be a Google Cloud Function. This could be combined with Cloud Endpoints, but not necessarily.
In the same Cloud Function, after a user's identity is checked, you call the speech API.
The API key could be stored as a secret in Google Secret Manager.
The Cloud Function acts as a "serving hatch" to the API, passing back and forth requests from a user to the Google Cloud Speech API.
Your API key remains on the backend, stored as a secret. Users that are not authenticated using the authentication provider, will never have access to the Speech API.

How to use WSO2 AM to call my backend services that are secured with OATH

Using my API Gateway WSO2, I want to call my backend services (my endpoints) that are secured with OAuth (ACCES-Token). But I cannot find how to do that.
It's even mentioned on the WSO2 website that by using API publisher (of WSO2 AM) you can only configure your APIs to call services secured with username/password : https://docs.wso2.com/display/AM210/Working+with+Endpoints
You cannot call backend services secured with OAuth through APIs created in the API Publisher. At the moment, you can call only services secured with username/password.
Do you know if there is another way to do this without using the API Publisher ?
Mu browser (SET API Gateway Access-Token) -- API Gatewau WSO2 (SET my Backend services Acess-Token) --> My backend services
Thank you !
You cannot call backend services secured with OAuth through APIs created in the API Publisher. At the moment, you can call only services secured with username/password.
Out-of-box from the API Publisher you can directly authenticate with the backend using Basic authentication (username and password)
Do you know if there is another way to do this without using the API Publisher ?
well - the Publisher app is always involved
I want to call my backend services (my endpoints) that are secured with OAuth (ACCES-Token)
There are multiple ways how to authenticate with the backend, not all are so straightforward
Basic authentication (this is what you don't want)
JWT token - the API Manager is able to send a signed JWT token with the API calls to the backend and the backend service could authenticate and extract client details from the JWT token.
Using the inbound mediation configuration you could manipulate the request payload and metadata
With the point 3 you should be able to send a custom OAuth/Authorization header. The question is - with what identity provider your service is authenticating/authorizing?
The problem is that there's no unified configuration how your service's client (API manager calling the backend) would fetch / cache / refresh / revoke the token which would work with all possible identity providers.
In theory you could implement the OAuth authentication with external IdP using the inbound mediations (sequences), but I strongly urge do not put anything complex as API mediation for sake of maintainability (been there, done that, screw it badly)
Maybe the simplest option would be having a permanent token you could pass in the HTTP headers, it sounds simple enough.
There is a custom Oauth2 mediator which you can try. https://github.com/imesh/wso2-oauth-mediator

Options for securing REST based service for iOS/Android app

I am working on a web application implementing online shopping functionality. I am using Struts2 + Spring + Hibernate. I am using Spring security to implement authorization and authentication.
Now my client wants to develop an iOS/Android App for the same where users of my web application can login and use some of the functionality using the app.
Mobile App will access the REST based web services on JSON which will be implemented using Jersey. Here are my questions:
Users are going to have a role from three of the roles. Depending on the role they should be able to access the specific resources. I am thinking about using Spring Security 2.0 with Jersey and authenticate the users using OAuth 2.0. Is OAuth 2.0 right applicable choice?
Also, Jersey doesn't support oAuth 2.0 on server side. Still I guess I should be able to use any other OAuth provider to secure Jersey services right?
If oAuth is not the right choice then what I can use to provide role based authentication and authorization for Mobile App users to my REST web services.
Don't forget you can use simple HTTP BASIC auth (with SSL, of course).
For comparsions of OAuth versions, see this.
After having to deal with the same problem I did some research and currently I can see 3 solutions.
Pivotal actually have a piece of software which they use for their cloudfoundry services, called UAA (User Account and Authentication) Server. You can deploy this to your own server, and it's role is basically to provide OAuth2 access tokens. You will need to create your own Resource Server which will serve different resources if the correct OAuth token is provided in the request. (they have a couple of sample apps in the UAA repo which you can use) https://github.com/cloudfoundry/uaa
Google actually provide services like that. If you host your backend on appengine you can use cloud endpoints to expose your API and they take care of Authentication and Authorization.
https://cloud.google.com/appengine/docs/java/endpoints/
You can create your own architecture. Basic approach would be to have an Authorization server (to generate tokens), an Resource Server (to serve your API) and some sort of storage for users and tokens.
Hope that helps a bit, I'm personally going to go with the UAA to try it out.