I am in the process of using a microsoft oauth2 workflow which starts by having a user signin to a portal granting an authorization code which is 'redeemed' for an access token and I'm having issues with the redeeming portion.
The script starts by opening a browser to a url that will send that authorization code to a local webserver which takes that code and sends another request to a microsoft endpoint which returns to error message: The request body must contain the following parameter: 'grant_type'.
Quick assumptions: my application is properly registered and configured, the redirect uri is added properly
import webbrowser
from http.server import BaseHTTPRequestHandler, HTTPServer
import requests
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("Thanks for logging in!", "utf-8"))
self.server.code = self.path.split("=")[1]
self.server.stop = True
global activationCode
activationCode = self.server.code
client_id = "client id here"
redirect_uri = "http://localhost:8080"
endpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id={}&response_type=code&redirect_uri={}&response_mode=query&scope={}&state={}".format(
client_id, # client id
redirect_uri, # redirect uri
"XboxLive.signin", # scope
"12345", # state
)
global activationCode
activationCode = None
httpServer = HTTPServer(("localhost", 8080), RequestHandler)
webbrowser.open(endpoint)
while not activationCode:
httpServer.handle_request()
print("Got activation code")
print("Fetching access token")
endpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token?client_id={}&scope={}&code={}&redirect_uri={}&grant_type=authorization_code".format(
client_id, # client id
"XboxLive.signin", # scope
activationCode, # code
redirect_uri, # redirect uri
)
res = requests.post(endpoint, headers={
"Content-Type": "application/x-www-form-urlencoded"
})
print(res.json())
The second request must be a POST, so send parameters like these in the body of the request to the token endpoint:
endpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"
body = {
"client_id": myclient,
"client_secret": mysecret,
"code": mycode,
"redirect_uri": myredirecturi,
"grant_type": "authorization_code"}
res = requests.post(
endpoint,
headers={
"Content-Type": "application/x-www-form-urlencoded"}
data=body
)