So far this is my code
import requests, json
API_ENDPOINT = 'https://discord.com/api/v8'
CLIENT_ID = '82'
CLIENT_SECRET = 'db'
REDIRECT_URI = 'https://google.com'
def refresh_token(refresh_token):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
js = json.loads(open("token.json", "r").read())
for i in js:
js[i] = refresh_token(js[i]["refresh_token"])
open("token.txt", "w").write(json.dumps(js))
Every time I run it, I get a 400 error
Traceback (most recent call last):
js[i] = refresh_token(js[i]["refresh_token"])
File "c:\Users\c\Downloads\discord-oauth2-example-master\discord-oauth2-example-master\refresh.py", line 18, in refresh_token
r.raise_for_status()
File "C:\Users\c\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\requests\models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://discord.com/api/v8/oauth2/token
The code is taken directly from the discord website, so i have no idea what is going wrong. My original token grants are working but not this. Any ideas?
Thanks
I think you should provide the scope key in the data object itself. The scope is the key that you initially set when you created the access_token;
Example of scope key that is separated by whitespace:
identify email guilds
If you check the discord-oauth2 library, it requires us to pass the "scope" key into the data object
https://www.npmjs.com/package/discord-oauth2
Related
I am attempting to authenticate with Microsoft Defender for Endpoint's API service by following this learn article:
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/run-advanced-query-sample-python?view=o365-worldwide#get-token
I typically use the "request" library for REST calls, so I didn't follow the above code snippet exactly. When running my version of the above code:
import json
import requests
MDE_CLIENT_ID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'
MDE_CLIENT_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
TENANT_ID = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'
AUTHORITY = 'https://login.microsoftonline.com/'
MDE_URI = 'https://api.securitycenter.microsoft.com'
class RESTError(Exception):
def __init__(self, status_code, message):
self.status_code = status_code
self.message = str(self.status_code) + ' ' + json.dumps(message)
super().__init__(self.message)
def authenticate_mde():
headers = {
'content-type': 'application/x-www-form-urlencoded'
}
body = {
'resource': MDE_URI,
'client_id': MDE_CLIENT_ID,
'client_secret': MDE_CLIENT_SECRET,
'grant_type': 'client_credentials'
}
response = requests.post(AUTHORITY + TENANT_ID + '/oauth2/token', data = json.dumps(body), headers = headers)
if (response.status_code < 200 or response.status_code > 299):
raise RESTError(response.status_code, response.json())
return response.json()['access_token']
def main():
token = authenticate_mde()
print(token)
if (__name__ == '__main__'):
main()
When I run this code I receive a 400 error back from the authentication service complaining about a missing body parameter 'grant_type'. However, as you can see in the code, I clearly have that included in the same fashion as the code snippet from MSFT.
Traceback (most recent call last):
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 42, in <module>
main()
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 38, in main
token = authenticate_mde()
File "C:\Users\24724\Documents\code\python\scripts\mde-executor.py", line 32, in authenticate_mde
raise RESTError(response.status_code, response.json())
__main__.RESTError: 400 {"error": "invalid_request", "error_description": "AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: e4d0d06e-aae6-4b6d-80e2-2b3997f74302\r\nCorrelation ID: 5788089d-f94e-4e9a-8667-d6e36c183af8\r\nTimestamp: 2023-01-06 17:00:23Z", "error_codes": [900144], "timestamp": "2023-01-06 17:00:23Z", "trace_id": "e4d0d06e-aae6-4b6d-80e2-2b3997f74302", "correlation_id": "5788089d-f94e-4e9a-8667-d6e36c183af8", "error_uri": "https://login.microsoftonline.com/error?code=900144"}
I also tried copying MSFT's code snippet exactly and inserting my own global var info but receive the same error. I have tried moving the body to url parameters, headers, splitting it up between body, params, and headers. No luck. I have tried different content-types in the header as well and tried without any headers. None seems to work and I am stumped at this point.
I resolved the issue. Passing 'resource' into the body was apparently screwing it up, even though their python example here shows that:
import json
import urllib.request
import urllib.parse
tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)
resourceAppIdUri = 'https://api.securitycenter.microsoft.com'
body = {
'resource' : resourceAppIdUri,
'client_id' : appId,
'client_secret' : appSecret,
'grant_type' : 'client_credentials'
}
data = urllib.parse.urlencode(body).encode("utf-8")
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
aadToken = jsonResponse["access_token"]
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/run-advanced-query-sample-python?view=o365-worldwide#get-token
Following the example they give for cURL here and using the 'scope' parameter instead fixed it.
curl -i -X POST -H "Content-Type:application/x-www-form-urlencoded" -d "grant_type=client_credentials" -d "client_id=%CLIENT_ID%" -d "scope=https://securitycenter.onmicrosoft.com/windowsatpservice/.default" -d "client_secret=%CLIENT_SECRET%" "https://login.microsoftonline.com/%TENANT_ID%/oauth2/v2.0/token" -k
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/exposed-apis-create-app-webapp?view=o365-worldwide#use-curl
I have Problem with scraping data from LinkedIn.
I think the documentation is too complicated ...
here the problem, I want to make a request (GET) and get for example data of my feed/posts/chats or whatever.
here is my code:
import json
import requests
# URL = "https://www.linkedin.com/voyager/api/voyagerMessagingDashConversationNudges"
URL = "https://www.linkedin.com/voyager/api/identity/dash/profiles"
cookies = {
#Cookies are here
}
params = {
'decorationId': 'com.linkedin.voyager.dash.deco.identity.profile.WebTopCardCore-6',
'memberIdentity': 'maria-albert-137632240',
'q': 'memberIdentity',
}
def get_group(url: str, cookies: dict, data:dict, header: dict):
response = requests.get(url=url, cookies=cookies, data=json.dumps(data), headers=header)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
print("sending request to Server:\n")
get_group(url=URL, cookies=cookies, data=params, header=headers)
but I couldn't do it, the error --> raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 400 Client Error: INKApi Error for url: https://www.linkedin.com/voyager/api/identity/dash/profiles
Thanks for your help.
You just need to set header like this:
header = {
"accept": 'application/vnd.linkedin.normalized+json+2.1',
"cookie": 'JSESSIONID="ajax:abcd"; li_at=abcdabcd',
}
and so fill the payload as the endpoint needed.
You don't have to Create App to access token or anything else.
I am writing a command line script accessing LinkedIN API via Library but having issues with it. Here is my code:
from linkedin import linkedin
import requests
RETURN_URL = "http://localhost"
authentication = linkedin.LinkedInAuthentication(CLIENT_ID, CLIENT_SECRET, RETURN_URL,
linkedin.PERMISSIONS.enums.values())
print(authentication.authorization_url)
get_code = authentication.authorization_url
application = linkedin.LinkedInApplication(authentication)
authentication.authorization_code = 'AQQfHou58eyVEJmbabHk1njdl-AY0bqfDjkZeosAn6DR-DiTnH7raJoDcign2U3w5w1YieYU4cjfTz3Ab-wa7cm3KwwctjzU-SoAWchjj_odArFM7q1W1CCU_15Q7gLDRrZoMCo5ivXnkisR5gYfGS0V2E_jsQ&state=74abc361c20313f5bc87d43f42f88b53#!'
# authentication.get_access_token()
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'redirect_uri': RETURN_URL,
'code': 'AQTqmP0g4PWGJpNnSysqvH4TCXTusoWsjbx1f3R7TPazYP4pCB81a4FrRJRUNjeJzH5yoN2XTrIT4YO-mu2VBQkhL12kwJZ09Xm_WHh97nyok0tqKHh8k54c3dCc075hrsJ8KYw02X-2XSMD-TkxQWKrUXPsMw&state=82d8d2bbbc80ba485812d2fe500cf3e9#!'
}
url = 'https://www.linkedin.com/uas/oauth2/accessToken'
r = requests.post(url, data=data)
print(r.text)
The error I get:
https://www.linkedin.com/uas/oauth2/authorization?client_id=862ztaa9740mst&redirect_uri=http%3A//localhost&scope=rw_company_admin%20r_emailaddress%20r_basicprofile%20w_share&response_type=code&state=d8e7aaefdbd32211fb7d342b238a84dc
{"error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired","error":"invalid_request"}
Also, how to get code part dynamically?
I'm trying to make an app that makes requests to Dynamics CRM Web API from python using urllib2.
So far I can login an user with an Azure application by making a post request to https://login.microsoftonline.com/common/oauth2/authorize
then with the retrieved authorization_code I can get the access_token, refresh_token and others with urllib2
url = 'https://login.microsoftonline.com/common/oauth2/token'
post_fields = {'grant_type': 'authorization_code',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'resource': 'https://graph.microsoft.com',
'code': code}
request = Request(url, urlencode(post_fields).encode())
resp = urlopen(request).read().decode()
resp = json.loads(resp)
refresh_token = resp['refresh_token']
id_token = resp['id_token']
id_token = jwt.decode(id_token,verify=False)
access_token = resp['access_token']
Then I tried to make another post request by using the access_token but had no luck.
I keep getting:
HTTP Error 401: Unauthorized
Just as a test I make a post directly to .dynamics.com/api/data/v8.1/leads
as follows:
url = 'https://<company_uri>.dynamics.com/api/data/v8.1/leads'
post_fields = {"name": "Sample Account",
"creditonhold": "false",
"address1_latitude": 47.639583,
"description": "This is the description of the sample account",
"revenue": 5000000,
"accountcategorycode": 1
}
request = Request(url, urlencode(post_fields).encode())
request.add_header('Authorization', 'Bearer ' + access_token )
request.add_header("Content-Type", "application/json; charset=utf-8")
request.add_header('OData-MaxVersion','4.0')
request.add_header('OData-Version','4.0')
request.add_header('Accept','application/json')
resp = urlopen(request).read().decode()
But i keep getting the same 401 error code.
I've looked all over msdn documentation but didn't find the way to do this directly without using any library, I just want to use a simple post request.
Since the error code says Unauthorized I think the access_token must be sent in some other way.
Can someone help me on how to correctly use the access_token on Dynamics CRM?
Thanks!
The access token you got back is for the Azure AD Graph API. Not Dynamics CRM.
To call that, you must ask for an access token with resource set to Dynamics CRM API's App ID URI, not https://graph.windows.net.
According to documentation you should set resource to https://<company_uri>.crm.dynamics.com.
So when you are retrieving token:
url = 'https://login.microsoftonline.com/common/oauth2/token'
post_fields = {'grant_type': 'authorization_code',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'resource': 'https://<company_uri>.crm.dynamics.com',
'code': code}
I wrote a small app to clean out errors in Google's Search Console (formally Google Webmaster Tools) using Oauth to connect accounts. This was running fine for the past two weeks, however, today I have noticed the the following error:
Error
Traceback (most recent call last):
File "/home/graingerkid/search_console_auto/scripts/error_count.py", line 97, in <module>
get_error_stats()
File "/home/graingerkid/search_console_auto/scripts/error_count.py", line 19, in get_error_stats
access_token = get_refreshed_tokens(refresh_token)
File "/home/graingerkid/search_console_auto/scripts/refresh_token.py", line 25, in get_refreshed_tokens
access_token = keys['access_token']
KeyError: 'access_token'
After investigating and trying to debug my code I realised I was not getting an access_token when requesting one with the refresh_token, here is the output:
Output
{
"error" : "invalid_grant"
}
Here is the function I wrote to grab the access_tokens (I've changed sensitive info):
Code
#-*- coding:utf-8 -*-
import json
import httplib2
import urllib
import pprint
def get_refreshed_tokens(refresh_token):
GOOGLE_CLIENT_ID = '98997543650-f0tn93u86vmts4j2m987654359shue6gu9g.apps.googleusercontent.com'
GOOGLE_CLIENT_SECRET = 'TFGZVLVG7VtnnrbNDTYFNBRgbfdFuENkBY'
h = httplib2.Http(".cache")
url = 'https://accounts.google.com/o/oauth2/token'
body = {
'client_secret': GOOGLE_CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
'client_id': GOOGLE_CLIENT_ID
}
headers = {'Content-type': 'application/x-www-form-urlencoded', 'cache-control': 'no-cache'}
response, content = h.request(url, 'POST', headers=headers, body=urllib.urlencode(body))
print content
keys = json.loads(content)
try:
access_token = keys['access_token']
except Exception as e:
pass
access_token = None
return access_token
get_refreshed_tokens('1/lWS6Fu3Hz5dMBPk9huVu6mt5yrnj5hrunhMEf7vs_UdibrBactUREZofsF9C7PrpE-j')
When requesting access to a users account I use the following:
google = oauth.remote_app('google',
base_url='https://www.google.com/accounts/',
authorize_url='https://accounts.google.com/o/oauth2/auth',
request_token_url=None,
request_token_params={'scope': 'https://www.googleapis.com/auth/webmasters https://www.googleapis.com/auth/userinfo.email',
'response_type': 'code',
'access_type':'offline',
'approval_prompt':'force'},
access_token_url='https://accounts.google.com/o/oauth2/token',
access_token_method='POST',
access_token_params={'grant_type': 'authorization_code'},
consumer_key=GOOGLE_CLIENT_ID,
consumer_secret=GOOGLE_CLIENT_SECRET)
Bearing in mind this worked fine for several weeks, I'm struggling to understand what's gone wrong, and searches on SO have not yielded answers.
Can anyone help with this?
(the accounts connected to these are mine, I have checked their access and the API access in Google API console is still intact, nothing has changed.)