I have a google cloud api gateway deployed to send requests to a cloud run service.
The cloud run service hosts a laravel docker container image and to authenticate with my authenticated pages, I need to send an Authorization header (Authorization: Bearer my-user-token-here).
When I send the request directly to the cloud run service, I am able to get the response I need with the Authorization header set. But, when I send the request through the api gateway, I always get an unauthenticated message showing the header is missing in the api request to the cloud run. I am not sure of this though.
I can't find any useful documentation on google cloud api gateway to suggest whether cloud run drops the header.
I am also not sure whether the error is from the openapi.yaml. So far I realized I cannot use the v3 of the openapi documentation but rather v2 as api gateway does not support v2. In the v2 of the openapi docs, the securityDefinitions don't support Authorization header Bearer token but instead supports Authorization header basic.
My Openapi yaml
# openapi2-run.yaml
swagger: "2.0"
info:
title: my-api
description: my custom api
version: 1.0.0
schemes:
- https
produces:
- application/json
consumes:
- application/json
x-google-backend:
address: https://some-cloud-run-url
basePath: /api
host: my-api.nw.gateway.dev
x-google-endpoints:
- name: "my-api.nw.gateway.dev"
allowCors: True
paths:
/user:
get:
summary: Requested user details.
operationId: UserDetails
responses:
"200":
description: Return Requested User Details.
schema:
type: string
"default":
description: Unexpected error
The surprising fact is that if I send the request either locally or directly to the cloud run, it works and I get no authentication error, but when I use the api-gateway, then I get the error. So I am guessing it has to do with the header going missing when the request reaches the cloud run, probably because the yaml definition I have here does not have an authorization header.
We have an API gateway instance which sends requests to cloud functions.
If any incoming requests have an Authorization header, the gateway maps the header details into an X-Forwarded-Authorization header in the request to the cloud function.
I assume it's the same for requests to Cloud Run. I don't have any experience with Laravel to know if it has options to look in the forwarded header, though.
Actually you can ignore it by setting the disable_auth in x-google-backend.
The document is not in google gateway, but in google endpoint as follow.
https://cloud.google.com/endpoints/docs/openapi/openapi-extensions
By the document it said:
When configuring your target backend, you may not want to use IAP or IAM to authenticate requests from ESPv2 if either of these conditions apply:
The backend should allow unauthenticated invocations.
The backend requires the original Authorization header from the API client and cannot use X-Forwarded-Authorization (described in the jwt_audience section).
So in your particular case, you just need to modify a single block like this:
x-google-backend:address:
https://some-cloud-run-url
disable_auth: True
And it will work like a charm.
Beware that once you decide to do the authorization yourself, you cannot set the securityDefinitions in the gateway config. The gcp gateway will throw 401 if you do this.
Related
What I want to do
Calling an URL which is proxied by the oauth2 proxy. The oauth2 proxy should perform an authorization code flow in case no authentication is available. In case there is already an authentication available, the access token should be set to the Authorization Header in the request which is forwarded to the upstream.
What I tried
According to the documentation I'd expect that, when setting --pass-authorization-header the token which is requested should be added to the authorization header.
I also experimented with --pass-access-token which should set an X-Forwarded-Access-Token header.
I couldn't see this header at my service either.
Could someone explain to me what I'm doing wrong?
I found the solution.
This post on a github issue lead me to my mistake.
I did misunderstand what the request is and what the response is and how to handle them using nginx ingresses.
If you are using OAuth2-Proxy with a Kubernetes ingress using nginx subrequests (https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/) the data that comes back to nginx is actually an HTTP response, so you will need to use HTTP Response headers (the --pass-* options configure request headers to the upstream).
Try --set-authorization-header and then you need to use this annotation to have the Kubernetes take the subrequest response header and add it to the proxied request header: nginx.ingress.kubernetes.io/auth-response-headers
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#external-authentication
I am working on an Elixir Phoenix web project where I want to interact with Google's Indexing API.
Google uses OAuth2 to authenticate api requests and actually has a decent documentation on this.
But it only explains the process using one of the supported libraries in Python, Java, PHP or JS.
I would like to make the HTTP requests by myself to retrieve that access token. But the request format (including headers or parameters) is nowhere documented and I cannot even figure out from the libraries' source code.
I have tried requesting https://accounts.google.com/o/oauth2/token (also other eligible URLs) in Postman with the "OAuth 2.0" request type.
But it was all just guessing and trying. All the research did not help.
There are useful instructions including HTTP/Rest examples at Using OAuth 2.0 for Web Server Applications. Each step has the individual parameters fully documented. Here are some useful excerpts.
Send user to Google's OAuth 2.0 server. Example URL:
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&
response_type=code&
client_id=client_id
Retreive authorization code (your domain). Example:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Request access token. Example:
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://oauth2.example.com/code&
grant_type=authorization_code
Use API. Example:
GET /drive/v2/files HTTP/1.1
Authorization: Bearer <access_token>
Host: www.googleapis.com/
I have never used Jmeter before. I have been trying to use Jmeter to send an HTTP request to Google Vision API - but it's returning a FORBIDDEN (403) error. My request as well as required response is in JSON format.
I have attached below the:
a) HTTP Request
b) Response Error
Other than this, in HTTP Header Manager I have set:
Content-Type: application/json
What is wrong with the attached request?
Request image..
Response error image
According to Authenticating to the Cloud Vision API article you might require to provide OAuth token, it can be done via HTTP Header Manager like:
Name: Authorization
Value: Bearer YOUR_ACCESS_TOKEN
See How to Run Performance Tests on OAuth Secured Apps with JMeter article for more details on interacting with OAuth-protected web applications in JMeter tests.
I want to use websocket to access Kubernetes API, and so it is more convenient to send token like wss://example.com" + url + "&access_token=blahblahblah. The official API doc sends token in header. Where can I find such a token and send it with url?
What I want to do is to exec pods via a web page through websocket:
Container-Terminal via Websocket
Support exec and pod logging over WebSockets
Bearer token authentication in the URL is not supported in Kubernetes currently, only as an Authorization header.
After searching over the Internet and reading many discussion on Kubernetes, I post my own answer about accessing kubernetes API with password in url, not header:
wss://username:myPassword#Address.To.Kubernetes/api/v1/namespaces/default/pods/YourPodName/exec?stdout=1&stdin=1&stderr=1&tty=1&command=%2Fbin%2Fsh
The username and password is in ~/.kube/config
Welcome answers for sending bearer token.
There is currently no way to send Authorization headers using native javascript WebSockets.
All third-party websocket libraries depend on the in-browser WebSocket class, which currently does not support custom headers. I tried a bunch of different libraries, but no luck :(
See Stack Overflow thread here: https://stackoverflow.com/a/4361358
The reason that this is not implemented is that Chromium/Chrome implementors are opposed to it. See the full discussion here: https://github.com/whatwg/websockets/issues/16#issuecomment-332065542
My workaround
Currently I'm working around this by using the #kubernetes/client-node in NodeJS to open a WebSocket connection.
The ws WebSocket library in NodeJS does support Authorization headers.
Then forwarding the NodeJS WebSocket messages to the front-end using Socket.io: https://stackoverflow.com/a/62547135.
Today I faced the problem that (suddenly) the SAP Gateway stopped acceppting CSRF tokens issued by himself.
Checked the network trace, everything is fine. The Client gets a token using GET Method and the HTTP Header
X-CSRF-Token: Fetch
receiving one, followed by an immediate POST request using the received Token and getting a 403 Forbidden status with response Body "CSRF Token could not be verified" (or similar)
By default, the CSRF Protection is only enabled over HTTPS in SAP Netweaver Gateway. How to enable CSRF over HTTP (and why not to do so) is described in the following SAP Note:
1896961 - HTTP/HTTPS Configuration for SAP NetWeaver Gateway
The important bit of the Note:
... set the instance profile parameter login/ticket_only_by_https to 0...