Python API request to internal API with OKTA Authentication - python

I used to selenium for downloading special reports from webpage where I have to login. Webpage has integrated OKTA Authentication plugin . I find out that there would be better and more effective use internal API requests. So I tried find how to use request python library with creating session, but I am unsuccessful. I tried this code, but it ends with 400 error.
payload = {"password":"password","username":"username","options":{"warnBeforePasswordExpired": True,"multiOptionalFactorEnroll": True}}
with requests.Session() as s:
p = s.post('https://sso.johndeere.com/api/v1/authn', data=payload)
r = s.get("requested_url")
print(p)
I am unable get throw auth. Has anybody experience with breaking OKTA auth plugin using requests library?
Thanks
Best Regards

Merry Christmas and Welcome to Stackoverflow!
Firstly, an HTTP error code of 400 error means one or more settings is wrong at the client side. You can learn more about it here.
You seem to be missing out important headers configuration. You need to set the content-type header correctly otherwise the destination server won't be able to process your data.
Also, as a bonus point. You need to format your payload into a valid JSON string before sending out the request too.
import requests
import json
# Setup proper headers
headers = {
"accept": "application/json, text/plain, */*",
"content-type": "application/json; charset=UTF-8"
}
# Your body data here
payload = {"password":"password","username":"username","options":{"warnBeforePasswordExpired": True,"multiOptionalFactorEnroll": True}}
payload_json = json.dumps(payload) # Format it into a valid JSON str
with requests.Session() as s:
p = s.post('https://sso.johndeere.com/api/v1/authn', headers=headers, data=payload_json)
r = s.get("requested_url")
print(p.content)

Related

Received Authentication Denied as Response while trying to get the access token (for Cloudhub.io) with requests library

I'm tying to get the data from the Cloudhub API which resides on Mulesoft.
I tried to access through postman (With the same Client Credentials - Bearer Authorization) and it's working fine (I can able to get the result with proper get requests).
But when I tried to do the same with Python requests library I ran into issues. Here is my piece of code:
import requests
import json, os
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_SECRET = os.environ['CLIENT_SECRET']
grant_type = 'client_credentials'
body_params = {'grant_type' : grant_type}
headers = {'Accept': '*/*',
'Cache-Control':'no-cache',
'Accept-Encoding': 'gzip, deflate',
'Content-Type':'application/json, application/x-www-form-urlencoded',
'Connection': 'keep-alive'}
url='https://<domain-name>-api.us-w2.cloudhub.io/api/token'
response = requests.post(url, data=body_params, auth = (CLIENT_ID, CLIENT_SECRET), headers= headers)
token_raw = json.loads(response.text)
print(token_raw)
Result: {'error': 'Authentication denied.'}
All I need to know is
How it's working fine with Postman but why I'm not able to connect with python code?
Is there anything I've to change in my code or any additional information needed for this request? or am I passing the correct endpoint in receiving the access token for Cloudhub API?
Please post your suggestions or any documentation that I need to refer.
Hope the information that I gave is clear and Thanks in Advance !!
I found the answer of my own question. I can get it from the postman itself.
Here is my code for API Call with Python.
import http.client
import os
conn = http.client.HTTPSConnection("<domain-name>-api.us-w2.cloudhub.io")
payload = ''
headers = {
'client_id': os.environ['CLIENT_ID'],
'client_secret': os.environ['CLIENT_SECRET']
}
conn.request("GET", "/api/<Query that you want to pass - endpoint>", payload, headers)
response = conn.getresponse()
resp_data = response.read()
print(resp_data.decode("utf-8"))
The URL is incorrect. To call CloudHub REST API you need to obtain a bearer token from Anypoint Platform REST API. The URL mentioned looks to for some application deployed in CloudHub, not from the platform APIs. This is the same method than to get the bearer token to use in Anypoint MQ Admin API. It looks like you are trying to use the Anypoint MQ Broker API, which is an Anypoint MQ specific token.
Example in Curl to get an Anypoint Platform token:
$ curl -H "Content-Type: application/json" -X POST -d '{"username":"joe.blogs","password":"sample.password"}' https://anypoint.mulesoft.com/accounts/login
{
"access_token": "f648eea2-3704-4560-bb46-bfff79712652",
"token_type": "bearer",
"redirectUrl": "/home/"
}
Additionally the Content-type of your example seems incorrect because it has 2 values.
I'm sure the Postman request is different for it to work, or maybe it works only for the Anypoint MQ Broker API.

How to send post to laravel api from python?

This is my python request code.
url = "https://test.com/"
r = requests.get(url, verify=False)
xsrf_token = r.cookies.get("XSRF-TOKEN")
headers = {
'X-XSRF-TOKEN':xsrf_token
}
data = {"account": "O_O#gmail.com", "password": "123123"}
r = requests.post(url+'/app/get/users', verify=False, data = data, headers=headers)
In laravel log, I got
[2019-12-27 16:09:14] local.ERROR: The payload is invalid. {"exception":"[object] (Illuminate\Contracts\Encryption\DecryptException(code: 0): The payload is invalid. at /var/www/html/test/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php:195)
[stacktrace]
Have any method to solve that? Thanks.
You can't solve the issue with a static xsrf alone since it's doing its job preventing Cross Site Request Forging wich is exactly what you're doing in that piece of code.
To use a route as an API, the laravel installation needs to be configured that way, so, if needed, a stateless way of authentification is used (jwt for example) instead of the session with xsrf token for post methods.
Basicly if it's not configured to be used as an API, you will not be able to use it as an API.

authentication using httplib in python

I am using python 2.7.10. How can I login using httplib connection method.
import httplib
conn = httplib.HTTPConnection("192.18.33.10")
conn.request("POST", "/user/user.form?name=Maharjun&age=23")
res = conn.getresponse()
data = res.read()
What this user.form does is, it will accept some details like name and age from users and server will save them in database. This details can only filled by authenticated users.
I tried some suggestions from python http.requests but those are not working in python-2.7.10.
I know about postman. So, I sent same request in postman using basic authentication method and i converted that into python scripts. In postman we can convert postman-URL into curl/shell/python scripts. So, I converted them into python scripts.
Both are same requests. But I am able to submit the data using postman. But not able to do with python.
postman is giving me a post-man token and basic authentication in headers like below code. is there any mistakes in the code or any suggestions?
import httplib
conn = httplib.HTTPConnection("192.18.33.10")
url = "/user/user.form?name=Maharjun&age=23"
headers = {
'authorization': "Basic some-token",
'cache-control': "no-cache",
'postman-token': "some-token"
}
response = conn.request("POST", url, headers=headers)
print(response.text)
Though it have 'authorization' token I was not able to login by using above code.
can someone help me to write basic authentication using python requests.?

HP QC REST API using python

I tried to connect HP QC using python to create defects and attach files, but I am not able to connect with HP QC. Here is my code:
domain='DEFAULT_773497139'
project='773497139_DEMO'
import requests
url = "https://almalm1250saastrial.saas.hpe.com/qcbin/"
querystring = {"username":"user#gmail.com","password":"password"}
headers = {
'cache-control': "no-cache",
'token': "5d33d0b7-1d04-4989-3349-3005b847ab7f"
}
response = requests.request("POST", url, headers=headers, params=querystring)
#~ print(response.text)
print response.headers
new_header = response.headers
new_url = url+ u'rest/domains/'+domain+u'/projects/'+project
new_querystring = {
"username":"user#gmail.com",
"password":"password",
"domain":'DEFAULT_773497139',
"project":'773497139_DEMO'
}
print new_url
response = requests.request("POST", new_url, headers=new_header, params=new_querystring)
print(response.text)
Now login works fine, but when try other API it asks for, I would get this message:
Authentication failed. Browser based integrations - to login append '?login-form-required=y' to the url you tried to access
If the parameter has been added, then it goes back to login page.
Seems that your urls are not well builded:
base_url ='https://server.saas.hpe.com/qcbin/'
base_url + '/qcbin/rest/domains/
you will get:
..../qcbin/qcbin/...
qcbin twice
The way I do it is to based on python request Sessions. First I create a session, then post my credentials to ../authentication-point/alm-authenticate/ (or sth like this, you should check it) and then using this session I can get, post or do whatever I want.
So:
s = requests.Session()
s.post(`../authentication-point/alm-authenticate/`, data=credentials)
# now session object is authenticated and recognized
# you can s.post, s.get or whatever
I think it's a good url, but I can't check it right now :)
Session issue has beensolved by LWSSO cookie (LWSSO_COOKIE_KEY).
Just send a unicode string to your server and use the header for the basic Authorization as specified by the HP REST API:
login_url = u'https://almalm1250saastrial.saas.hpe.com/qcbin/authentication-point/authenticate'
username,password = user,passwd
logs = base64.b64encode("{0}:{1}".format(username, password))
header['Authorization'] = "Basic {}".format(logs)
POST by using the requests module in python is quite easy:
requests.post(login_url, headers=header)
That's it...now you are authenticated and you can proceed with next action :-) To check on that you can "GET" on:
login_auth = u'https://almalm1250saastrial.saas.hpe.com/qcbin/rest/is-authenticated
you should get a code 200 --> That means you are authenticated.
Hope this help you. Have a nice day and let me know if something is still not clear.
p.s.: to send REST msg in python I am using requests module. It is really easy! You can create a session if you want to send multiple actions--> then work with that sessions--> ALM = requests.session(), then use ALM.post(whatever) and so on :-)

Google Data API authentication

I am trying to get my Django app (NOT using Google app engine) retrieve data from Google Contacts using Google Contacts Data API. Going through authentication documentation as well as Data API Python client docs
First step (AuthSubRequest) which is getting the single-use token works fine. The next step(AuthSubSessionToken), which is upgrade single-use token to a session token. The python API call UpgradeToSessionToken() simply didn't work for me it gave me NonAuthSubToken exception:
gd_client = gdata.contacts.service.ContactsService()
gd_client.auth_token = authsub_token
gd_client.UpgradeToSessionToken()
As an alternative I want to get it working by "manually" constructing the HTTP request:
url = 'https://www.google.com/accounts/AuthSubSessionToken'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'AuthSub token=' + authsub_token,
'User-Agent': 'Python/2.6.1',
'Host': 'https://www.google.com',
'Accept': 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
'Connection': 'keep-alive',
}
req = urllib2.Request(url, None, headers)
response = urllib2.urlopen(req)
this gives me a different error:
HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop. The last 30x error message was: Moved Temporarily
What am I doing wrong here? I'd appreciate help/advice/suggestions with either of the methods I am trying to use: Python API call (UpgradeToSessionToken) or manually constructing HTTP request with urllib2.
According to the 2.0 documentation here there is a python example set...
Running the sample code
A full working sample client, containing all the sample code shown in this document, is available in the Python client library distribution, under the directory samples/contacts/contacts_example.py.
The sample client performs several operations on contacts to demonstrate the use of the Contacts Data API.
Hopefully it will point you in the right direction.
I had a similar issue recently. Mine got fixed by setting "secure" to "true".
next = 'http://www.coolcalendarsite.com/welcome.pyc'
scope = 'http://www.google.com/calendar/feeds/'
secure = True
session = True
calendar_service = gdata.calendar.service.CalendarService()
There are four different ways to authenticate. Is it really that important for you to use AuthSub? If you can't get AuthSub to work, then consider the ClientLogin approach. I had no trouble getting that to work.

Categories

Resources