Authenticating service-to-service on GCP fails from local machine - python-3.x

I am trying to authenticate, however the requests library in python3 does not let me fetch the token. Using the following code example: https://cloud.google.com/run/docs/authenticating/service-to-service#python
# Requests is already installed, no need to add it to requirements.txt
import requests
receiving_service_url = "https://myproject....run.app"
# Set up metadata server request
# See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_request_url = metadata_server_token_url + receiving_service_url
token_request_headers = {'Metadata-Flavor': 'Google'}
# Fetch the token
### CRASHES HERE ###
token_response = requests.get(token_request_url, headers=token_request_headers) ###
### CRASHES HERE ###
jwt = token_response.content.decode("utf-8")
# Provide the token in the request to the receiving service
receiving_service_headers = {'Authorization': f'bearer {jwt}'}
service_response = requests.get(receiving_service_url, headers=receiving_service_headers)
print(service_response.content)
If i run the same code inside the Console in gcp, with iPython, it can fetch the token. And I can use it from my local machine with e.g CURL.
Error:
token_response = requests.get(token_request_url, headers=token_request_headers)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='metadata', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/identity?audience=https://myproject....run.app (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f87f0573370>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
INFO:werkzeug:127.0.0.1 - - [08/Oct/2020 23:54:14] "GET / HTTP/1.1" 200 -
Why cant I establish a connection when running this on my local machine?

If you base your code on metadata server, it will works only on Google Cloud. I answered this question yesterday, and I think, you can get inspiration from it.
Instead of using the metadata server, you can use the IAM rest API to generateIDToken. Like this, it works locally and in the cloud.
The code is a bit longer, and I don't know if the IAM API is as efficient as metadata servers.
If you need details and explanation, don't hesitate to comment!

Related

werkzeug.exceptions.ClientDisconnected: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand

code(python):
try:
xxx
try:
post_dic = request.get_json()
req_ip = request.remote_addr
except Exception as error:
logging.error("xxx")
error logging:
Tue, 29 Mar 2022 17:44:12 data_preprocess_server.py[line:223]|[ERROR] [new_data__
processor]: get input data failed, you must use Content-Type: application/json,
logId=[xxx], Exception=[400 Bad Request: The brr
owser (or proxy) sent a request that this server could not understand.], tracebaa
ck=[Traceback (most recent call last):
File "xxx.py", line 220, in new_data_preprocess
post_dic = request.get_json()
File "/xxx/python3832/lib/python3.8/site-packages/werkzeug/wrappp
ers/request.py", line 583, in get_json
data = self.get_data(cache=cache)
File "/xxx/python3832/lib/python3.8/site-packages/werkzeug/wrappp
ers/request.py", line 424, in get_data
rv = self.stream.read()
File "/xxx/python3832/lib/python3.8/site-packages/werkzeug/wsgi..
py", line 925, in read
return self.on_disconnect()
File "/xxx/python3832/lib/python3.8/site-packages/werkzeug/wsgi..
py", line 893, in on_disconnect
raise ClientDisconnected()
werkzeug.exceptions.ClientDisconnected: 400 Bad Request: The browser (or proxy)
sent a request that this server could not understand.
i want to learn about how to fix this question by my role who provide the service, because i can't ask the roles who request my service to try to fix this bug, like increase the connection time or use retry

Python3 Slack RTMClient in not working behind proxy

I am trying to create a simple Python bot for my project. Everything is working fine on my localhost, but the same code stops working behind the network firewall which needs environment proxy to be set.
from slack import RTMClient
proxy='http://XXXX:NNNN'
token='XXXX'
class Botso():
def __init__(self):
self.proxy=self.get_proxy()
self.rt= RTMClient(
token=token,
connect_method='rtm.start',
proxy=self.proxy
)
def get_proxy(self):
host=socket.gethostname()
if "internal" in host:
return None
elif "XXX" in host:
return proxy
#RTMClient.run_on(event="message")
def say_hello(**payload):
data = payload['data']
web_client = payload['web_client']
if 'text' in data and 'hii' in data['text']:
channel_id = data['channel']
thread_ts = data['ts']
user = data['user'] # This is not username but user ID (the format is either U*** or W***)
web_client.chat_postMessage(
channel=channel_id,
text=f"Hi <#{user}>!"
#thread_ts=thread_ts
)
if __name__ == '__main__':
botso=Botso()
botso.rt.start()
The error I am getting while initializing the RTMClient is
Traceback (most recent call last):
File "botso.py" , in <module>
botso.rt.start()
File "/usr/lib64/python3.6/http/client.py", line 974, in send
self.connect()
File "/usr/lib64/python3.6/http/client.py", line 1407, in connect
super().connect()
File "/usr/lib64/python3.6/http/client.py", line 950, in connect
self._tunnel()
File "/usr/lib64/python3.6/http/client.py", line 929, in _tunnel
message.strip()))
OSError: Tunnel connection failed: 403 Forbidden
I have other code in the same environment which uses the same proxy to send slack messages and works fine bu using request api.
params={
'token': self.slack_token,
'types': ['public_channel','private_channel']
}
slack_url='https://slack.com/api/conversations.list'
response = requests.get(url=slack_url,params=params,proxies=self.proxy).json()
How can we make the RTMClient work with proxy and Python3.
Couldn't find much help in slack API documents.

Python3.5 openssl error when validating certificate [duplicate]

I'm calling a REST API with requests in python and so far have been successful when I set verify=False.
Now, I have to use client side cert that I need to import for authentication and I'm getting this error everytime I'm using the cert (.pfx). cert.pfx is password protected.
r = requests.post(url, params=payload, headers=headers,
data=payload, verify='cert.pfx')
This is the error I'm getting:
Traceback (most recent call last):
File "C:\Users\me\Desktop\test.py", line 65, in <module>
r = requests.post(url, params=payload, headers=headers, data=payload, verify=cafile)
File "C:\Python33\lib\site-packages\requests\api.py", line 88, in post
return request('post', url, data=data, **kwargs)
File "C:\Python33\lib\site-packages\requests\api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python33\lib\site-packages\requests\sessions.py", line 346, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python33\lib\site-packages\requests\sessions.py", line 449, in send
r = adapter.send(request, **kwargs)
File "C:\Python33\lib\site-packages\requests\adapters.py", line 322, in send
raise SSLError(e)
requests.exceptions.SSLError: unknown error (_ssl.c:2158)
I've also tried openssl to get .pem and key but with .pem and getting SSL: CERTIFICATE_VERIFY_FAILED
Can someone please direct me on how to import the certs and where to place it? I tried searching but still faced with the same issue.
I had this same problem. The verify parameter refers to the server's certificate. You want the cert parameter to specify your client certificate.
import requests
cert_file_path = "cert.pem"
key_file_path = "key.pem"
url = "https://example.com/resource"
params = {"param_1": "value_1", "param_2": "value_2"}
cert = (cert_file_path, key_file_path)
r = requests.get(url, params=params, cert=cert)
I had the same problem and to resolve this, I came to know that we have to send RootCA along with certificate and its key as shown below,
response = requests.post(url, data=your_data, cert=('path_client_certificate_file', 'path_certificate_key_file'), verify='path_rootCA')

Sending my first message on the slack API

I registered my first app, and it looks like this:
All of the fields are populated below the screen shot.
Now, I have some basic python code using the examples found on their repo.
I create the following test script:
import traceback
app_id = 'FAKE.VALUE'
client_id = 'FAKE.VALUE'
client_secret = 'FAKE.VALUE'
signin_secret = 'FAKE.VALUE'
verification_token = 'FAKE.VALUE'
items = locals()
import os
import slack
items = locals().copy()
for k in items:
if '__' not in k:
val = items[k]
try:
client = slack.WebClient(token=val)
response = client.chat_postMessage(
channel='CE476K9HT',
text='Hello-----' + str(val))
print(response)
except:
print(k)
traceback.print_exc()
print('-'*50)
But all of the responses I get say:
The server responses with: {'ok':False,'error':'invalid_auth'}
For some reason, is it necessary to use path variables?
It is unclear to me what type of auth is required here.
After doing what Erik suggested,
I have a xoxp code and registered the redirect url to http://localhost.
and added the following scopes:
and updated my code to look like:
oauth_token ='xoxp-*****************'
import os
import slack
items = locals().copy()
client = slack.WebClient(token=oauth_token)
response = client.chat_postMessage(
channel='my_channel_id',
text='Hello-----')
I got my channel ID from the url:
https://app.slack.com/client/FOO/my_channel_id
When I run my code, I get the following back:
Traceback (most recent call last):
File "/home/usr/git/slack_messaging/slack_messaging.py", line 20, in <module>
text='Hello-----')
File "/home/usr/git/python-slackclient/slack/web/client.py", line 382, in chat_postMessage
return self.api_call("chat.postMessage", json=kwargs)
File "/home/usr/git/python-slackclient/slack/web/base_client.py", line 172, in api_call
return self._event_loop.run_until_complete(future)
File "/home/usr/anaconda2/envs/beer/lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
return future.result()
File "/home/usr/git/python-slackclient/slack/web/base_client.py", line 241, in _send
return SlackResponse(**{**data, **res}).validate()
File "/home/usr/git/python-slackclient/slack/web/slack_response.py", line 176, in validate
raise e.SlackApiError(message=msg, response=self)
slack.errors.SlackApiError: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'missing_scope', 'needed': 'chat:write:user', 'provided': 'admin,identify'}
Process finished with exit code 1
You need two things to make your script work.
1. OAuth token
You need a valid OAuth token and provide it when initializing the Slack Client:
client = slack.WebClient(token="xoxb-xxx")
To get a token you need to install your Slack app to a workspace. You can do that on the app management page under "Install App". Your OAuth token will also be displayed on that page once you installed it.
2. Permissions
Your Oauth Token / Slack app needs to have the permission to post messages. On the app management pages go to "OAuth & permission" and add the needed permission to your app:. e.g. chat:write:user for user tokens.
Note that you need to reinstall your app every time to add a permission.

SSL error using direct IP address with Python3's Requests library

I'm trying to access "https://google.com" via direct IP address (172.217.0.78)
I gave host header and specified it correctly, but I still got the error.
Could anyone help me figure how we can get around?
requests.get("https://172.217.0.78", headers={"Host": "google.com"}, verify=True)
UNCAUGHT EXCEPTION SSLError: hostname '172.217.0.78' doesn't match either of '*.google.com', '*.android.com', '*.appengine.google.com', '*.cloud.google.com', '*.db833953.google.cn', '*.g.co', '*.gcp.gvt2.com', '*.google-analytics.com', '*.google.ca', '*.google.cl', '*.google.co.in', '*.google.co.jp', '*.google.co.uk', '*.google.com.ar', '*.google.com.au', '*.google.com.br', '*.google.com.co', '*.google.com.mx', '*.google.com.tr', '*.google.com.vn', '*.google.de', '*.google.es', '*.google.fr', '*.google.hu', '*.google.it', '*.google.nl', '*.google.pl', '*.google.pt', '*.googleadapis.com', '*.googleapis.cn', '*.googlecommerce.com', '*.googlevideo.com', '*.gstatic.cn', '*.gstatic.com', '*.gvt1.com', '*.gvt2.com', '*.metric.gstatic.com', '*.urchin.com', '*.url.google.com', '*.youtube-nocookie.com', '*.youtube.com', '*.youtubeeducation.com', '*.yt.be', '*.ytimg.com', 'android.clients.google.com', 'android.com', 'developer.android.google.cn', 'developers.android.google.cn', 'g.co', 'goo.gl', 'google-analytics.com', 'google.com', 'googlecommerce.com', 'source.android.google.cn', 'urchin.com', 'www.goo.gl', 'youtu.be', 'youtube.com', 'youtubeeducation.com', 'yt.be'
<stdin>:1 [<module>]
/usr/lib/python3/dist-packages/requests/api.py:65 [get] return request('get', url, **kwargs)
/usr/lib/python3/dist-packages/requests/api.py:49 [request] response = session.request(method=method, url=url, **kwargs)
/usr/lib/python3/dist-packages/requests/sessions.py:461 [request] resp = self.send(prep, **send_kwargs)
/usr/lib/python3/dist-packages/requests/sessions.py:573 [send] r = adapter.send(request, **kwargs)
/usr/lib/python3/dist-packages/requests/adapters.py:431 [send] raise SSLError(e, request=request)

Resources