Retrieving data from Streamsets Data Collector (SDC) protected by Kerberos - python-2.7

I am trying to retrieve data from the SDC API protected by Kerberos. Initially i am posting the credentials to the SCH login page and then using the cookies generated to access the SDC rest api. However, i am not able to post the credentials. Response code is 401 and hence not able to access api.
dpm_auth_creds = {"userName":"", "password":"" }
headers = {"Content-Type": "application/json", "X-Requested-By": "SDC"}
auth_request = requests.post("https://url:18641/sch/security/users" , data=json.dumps(dpm_auth_creds), headers=headers, verify="file.pem")
cookies = auth_request.cookies
print(auth_request.status_code)
print(auth_request.headers)
url = requests.get("https://url:18641/jobrunner/rest/v1/sdcs", cookies=cookies)
print(url.text)
Response code is 401: for auth_request.status_code

This is from the REST API page in Control Hub:
# login to Control Hub security app
curl -X POST -d '{"userName":"DPMUserID", "password": "DPMUserPassword"}' https://cloud.streamsets.com/security/public-rest/v1/authentication/login --header "Content-Type:application/json" --header "X-Requested-By:SCH" -c cookie.txt
# generate auth token from security app
sessionToken=$(cat cookie.txt | grep SSO | rev | grep -o '^\S*' | rev)
echo "Generated session token : $sessionToken"
# Call SDC REST APIs using auth token
curl -X GET https://cloud.streamsets.com/security/rest/v1/currentUser --header "Content-Type:application/json" --header "X-Requested-By:SCH" --header "X-SS-REST-CALL:true" --header "X-SS-User-Auth-Token:$sessionToken" -i
So your Python code should be more like:
dpm_auth_creds = {"userName":"", "password":"" }
headers = {"Content-Type": "application/json", "X-Requested-By": "SDC"}
auth_request = requests.post("https://url:18641/security/public-rest/v1/authentication/login" , data=json.dumps(dpm_auth_creds), headers=headers, verify="file.pem")
cookies = auth_request.cookies
print(auth_request.status_code)
print(auth_request.headers)
# Need to pass value of SS-SSO-LOGIN cookie as X-SS-User-Auth-Token header
headers = {
"Content-Type":"application/json",
"X-Requested-By":"SCH",
"X-SS-REST-CALL":"true",
"X-SS-User-Auth-Token":auth_request.cookies['SS-SSO-LOGIN']
}
url = requests.get("https://url:18641/jobrunner/rest/v1/sdcs", headers=headers)
print(url.text)

Related

Integrating Sagepay (Opayo) with Django - How to create a merchant session key

I am trying to integrate Opayo (SagePay) with Django and I am having problems generation the merchant session key (MSK).
From sagepays docs they say to use the below curl request and that I should receive the key in the response
curl https://pi-test.sagepay.com/api/v1/merchant-session-keys \
-H "Authorization: Basic aEpZeHN3N0hMYmo0MGNCOHVkRVM4Q0RSRkxodUo4RzU0TzZyRHBVWHZFNmhZRHJyaWE6bzJpSFNyRnliWU1acG1XT1FNdWhzWFA1MlY0ZkJ0cHVTRHNocktEU1dzQlkxT2lONmh3ZDlLYjEyejRqNVVzNXU=" \
-H "Content-type: application/json" \
-X POST \
-d '{
"vendorName": "sandbox"
}'
I have tried to implement this in my Django view with the following code but I receive a 422 response (Unprocessable Entity response).
import requests
def BasketView(request):
headers = {
"Authorization": "Basic aEpZeHN3N0hMYmo0MGNCOHVkRVM4Q0RSRkxodUo4RzU0TzZyRHBVWHZFNmhZRHJyaWE6bzJpSFNyRnliWU1acG1XT1FNdWhzWFA1MlY0ZkJ0cHVTRHNocktEU1dzQlkxT2lONmh3ZDlLYjEyejRqNVVzNXU=",
"Content-type": "application/json",
}
data = {"vendorName": "sandbox"}
r = requests.post("https://pi-test.sagepay.com/api/v1/merchant-session-keys", headers=headers, params=data)
print(r)
Any ideas where I may be going wrong with this?
You are passing the wrong parameter to requests.post() you should use jsoninstead of params:
r = requests.post(
"https://pi-test.sagepay.com/api/v1/merchant-session-keys",
headers=headers,
json=data
)
By doing so, there is no need to specify the Content-Type header, it is added automatically.

How to do akka http request for oauth2 access_token

I am trying to request auth server to get access_token . I have a working curl command , but am unable to implement using Akka HTTP.
curl -v -u CLIENT_ID:CLIENT_SECRET -k -X POST -d {} 'URL/oauth2/token?grant_type=client_credentials&scope=Scope'
or
curl -i -H 'Authorization: Basic Base64(CLIENT_ID:CLIENT_SECRET)' --request POST URL/oauth2/token -d 'grant_type=client_credentials&scope=scope'
i am getting 405 Method Not Allowed error while requesting using http.singleRequest
def getToken(url:String, user: String, pass: String, scope:String) = {
Http()
.singleRequest(
Post(
Uri(url),
Map("grant_type" -> "client_credentials", "scope" -> s"$scope"),
).withHeaders(
Authorization(BasicHttpCredentials(user, pass)),
),
)
}
val request = HttpRequest(
HttpMethods.POST,
config.authDomain,
entity = FormData
.apply(
Map(
"grant_type" -> s"${config.grant_type}",
"scope" -> s"${config.api_scope}",
),
)
.toEntity,
).withHeaders(Authorization(BasicHttpCredentials(config.access_id, config.access_secret)))

how to authenticate in HTTPS by NetHTTPClient

Hello
I must stress that I dont want use curl, and I must use only Embarcadero compiler. (C++Builder and Delphi)
I want send a request to a server which need authentication.
The complete command by API documentation is:
curl -X POST "https://api.demo.website.com/api/2/something" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "symbol=BTC&side=buy&type=limit&timeInForce=GTC&quantity=0.1&price=4000"
Their Authentication style they provide is:
curl -u "publicKey:secretKey" https://api.demo.website.com/api/2/something
Their suggested code is: (which is not C++) :-))
import requests
session = requests.session()
session.auth = ("publicKey", "secretKey")
const fetch = require('node-fetch');
const credentials = Buffer.from('publicKey' + ':' + 'secretKey').toString('base64');
fetch('https://api.demo.website.com/api/2/something', {
method: 'GET',
headers: {
'Authorization': 'Basic ' + credentials
}
});
My Code is:
TCredentialsStorage::TCredential *MyCredential = new TCredentialsStorage::TCredential(
TAuthTargetType::Server, "", "",
UserNameEdit->Text, PasswordEdit->Text);
NetHTTPClient1->CredentialsStorage->AddCredential(*MyCredential);
StatMemo->Lines->Add(IntToStr(NetHTTPClient1->CredentialsStorage->Credentials.RefCount));
TMemoryStream *Response=new TMemoryStream;
TMemoryStream *bbkTMS =new TMemoryStream;
TNameValueArray nva;
NetHTTPRequest1->Post(URLEdit->Text, bbkTMS, Response, nva);
StatMemo->Lines->LoadFromStream(bbkTMS);
Memo1->Lines->LoadFromStream(Response);
The code is compiling but ot working... :-|
It said:
{"error":{"code":1004,"message":"Unsupported authorization method"}}
Any suggestion for me?
I find it out :-)
As I am using RAD Tool (Embarcadero) So I can use its VCL/FMX component:
THTTPBasicAuthenticator
Done!
But instead NetHTTP component group I start using RESTClient component group, much more better.

AWS Presigned URL works with Python's Requests library but fails with cURL

Recently I started using AWS pre-signed URLs to upload files to S3. The generated pre-signed URLs are working perfectly when using Python's Requests library as follows:
Generating the pre-signed url:
def create_presigned_post(bucket_name, object_name,
fields=None, conditions=None, expiration=3600):
"""Generate a presigned URL S3 POST request to upload a file
:param bucket_name: string
:param object_name: string
:param fields: Dictionary of prefilled form fields
:param conditions: List of conditions to include in the policy
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Dictionary with the following keys:
url: URL to post to
fields: Dictionary of form fields and values to submit with the POST
:return: None if error.
"""
# Generate a presigned S3 POST URL
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_post(bucket_name,
object_name,
Fields=fields,
Conditions=conditions,
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL and required fields
return response
Running the request to get the presigned url
# Getting a presigned_url to upload the file into S3 Bucket.
headers = {'Content-type': 'application/json', 'request': 'upload_url', 'target': FILENAME, 'x-api-key': API_KEY}
r_upload = requests.post(url = API_ENDPOINT, headers = headers)
url = json.loads(json.loads(r_upload.text)['body'])['url']
fields_ = json.loads(json.loads(r_upload.text)['body'])['fields']
fields = {
"x-amz-algorithm": fields_["x-amz-algorithm"],
"key": fields_["key"],
"policy": fields_["policy"],
"x-amz-signature": fields_["x-amz-signature"],
"x-amz-date": fields_["x-amz-date"],
"x-amz-credential": fields_["x-amz-credential"],
"x-amz-security-token": fields_["x-amz-security-token"]
}
fileobj = open(FILENAME, 'rb')
http_response = requests.post(url, data=fields,files={'file': (FILENAME, fileobj)})
Valid Response
"{\"url\": \"https://****.s3.amazonaws.com/\",
\"fields\":
{\"key\": \"******\", \"x-amz-algorithm\": \"*******\", \"x-amz-credential\": \"*******\", \"x-amz-date\": \"*********\", \"x-amz-security-token\": \"********", \"policy\": \"**********\", \"x-amz-signature\": \"*******\"}}
And as you can see I'm providing no AWSAccessKey or any credentials when uploading the file using the generated pre-signed URL and this is so logical, as the pre-signed URL is created to be given for external users who have to provide no credentials when using such URL.
However and when trying to run the same call made by Python's Requests library, using cURL, the request is failing with the error:
< HTTP/1.1 403 Forbidden
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><Error>
To get the exact request call made by requests.post, I'm running:
req = http_response.request
command = "curl -X {method} -H {headers} -d '{data}' '{uri}'"
method = "PUT"
uri = req.url
data = req.body
headers = ['"{0}: {1}"'.format(k, v) for k, v in req.headers.items()]
headers = " -H ".join(headers)
print(command.format(method=method, headers=headers, data=data, uri=uri))
Which returns:
curl -v -X PUT -H "Connection: keep-alive" --upload-file xxxx.zip -H "Accept-Encoding: gzip, deflate" -H "Accept: */*" -H "User-Agent: python-requests/2.18.4" -H "Content-Length: xxxx" -H "Content-Type: multipart/form-data; boundary=8a9864bdxxxxx00100ba04cc055a" -d '--8a9864bd377041xxxxx04cc055a
Content-Disposition: form-data; name="x-amz-algorithm"
AWS4-HMAC-SHA256
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="key"
xxxxx.zip
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="x-amz-signature"
*****
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="x-amz-security-token"
*****
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="x-amz-date"
*****
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="policy"
*****
--8a9864bd377041e0b00100ba04cc055a
Content-Disposition: form-data; name="x-amz-credential"
xxxxx/xxxxx/xxxx/s3/aws4_request
' 'https://xxxxx.s3.amazonaws.com/'
Then reformulate it:
$ curl -v -T file "https://****.s3.amazonaws.com/?key=************&x-amz-algorithm=***************&x-amz-credential=*************&x-amz-security-token=************&policy=**********&x-amz-signature=****************
After researching, I found nothing similar to this issue, but:
https://aws.amazon.com/es/premiumsupport/knowledge-center/s3-access-denied-error/
This still seem not logical to me because I'm not supposed to enter any credentials when using a pre-signed URL.
I don't know if I'm missing something of the complete request made by Python's Requests library.
Any ideas, please!
Kind regards,
Rshad
This simple curl command should work:
With a usual presigned url, it would be as follows:
curl -v \
-F key=<filename> \
-F x-amz-algorithm=*** \
-F x-amz-credential=*** \
-F x-amz-date=*** \
-F x-amz-security-token=*** \
-F policy=*** \
-F x-amz-signature=*** \
-F file=#<filename> \
'https://<bucket>.s3.amazonaws.com/'
The -F field allows you to specify the additional POST data that should be uploaded to S3 (i.e. from the fields data returned w/ the pre-signed URLs.
Kind regards,

Error while generating authentication token in Django Rest Framework

I have created an endpoint localhost:8000/getauthtoken to generate the authentication token.
The curl command that i am using to get the authentication token is:
curl --request POST --url localhost:8000/getauthtoken --header 'content-type: application/json' --data '{"username":"admin", "password":"admin123"}'
But i am getting
{"password":["This field is required."],"username":["This field is required."]}
But in the command i am passing both username and password
As per the DRF documentation http://www.django-rest-framework.org/api-guide/authentication/ this is the correct way.
Use httpie (available on pypi)
Then follow this on terminal:
Http post your_ip:your_port/your_authresource/ username='' password=''
Or you can try that in Curl in right way:
curl -X POST http://localhost:8000/api-token-auth/ -d "password=aaaaa&username=user"