โ04-01-2024 11:44 AM
I am writing a frontend webpage that will log into DataBricks and allow the user to select datasets.
I am new to front end development, so there may be some things I am missing here, but I know that the DataBricks SQL connector for javascript only works with Node, which does not work client side. I am aware that there are ways to shoehorn node packages into running in the browser but I am trying to avoid this.
I am looking into using OAuth U2M with manual token generation, as outlined in this article https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-u2m#--manually-generate-and-...
I am able to generate the authorization code in the browser URL just fine (Step 2). However, when I get to the step of generating an OAuth access token (Step3: https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-u2m#--step-3-use-the-authori...), the POST request always returns a 400 with a response of {"error":"invalid_request","error_description":"Invalid authorization code"}
This post request I am doing in python, just as a proof of concept, but I would implement the whole system client side in javascript.
Here is the script I am using for the proof of concept. Any advice on why I keep receiving a 400 would be appreciated. Thanks!
import uuid, hashlib, base64, requests, json, webbrowser
# Generate a UUID.
uuid1 = uuid.uuid4()
# Convert the UUID to a string.
uuid_str1 = str(uuid1).upper()
# Create the code verifier.
code_verifier = uuid_str1 + "-" + uuid_str1
# Create the code challenge based on the code verifier.
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode('utf-8')
# Remove all padding from the code challenge.
code_challenge = code_challenge.replace('=', '')
print(f"code_verifier: {code_verifier}")
print(f"code_challenge: {code_challenge}")
account_id = "**** MY ACCOUNT ID ****"
redirect_url = "http://localhost:8020"
url1 = f"https://accounts.azuredatabricks.net/oidc/accounts/{account_id}/v1/authorize?client_id=databricks-cli&redirect_url={redirect_url}&response_type=code&state=helloworld&code_challenge={code_challenge}&code_challenge_method=S256&scope=all-apis+offline_access"
webbrowser.open(url1, new=2, autoraise=True)
################### Get code from browser
auth_code = "********" # code from browser
body = {"client_id":"databricks-cli","grant_type":"authorization_code","scope":"all-apis offline_access",
"redirect_uri":redirect_url, "code_verifier":code_verifier,"code":auth_code}
url2 = f"https://accounts.azuredatabricks.net/oidc/accounts/{account_id}/v1/token"
r = requests.post(url=url2, data=body)
#This returns
#<Response [400]>
#b'{"error":"invalid_request","error_description":"Invalid authorization code"}'
โ04-02-2024 04:20 AM
Hi @BenDataBricks,
auth_code
variable in your Python script contains the correct authorization code obtained from the browser.code_verifier
youโre using matches the one you generated earlier.redirect_url
matches the one youโve set up for your application.โ07-25-2024 11:13 PM
@Kaniz_Fatma I am facing the same issue even though ensured all criteria you mentioned previously.
โ07-25-2024 11:23 PM
Hi @MaheshMandlik and @BenDataBricks, If you have already verified that the authorization code, code verifier, code challenge, redirect URI, client ID, and account ID are all correct, and you are still receiving a 400 error with "invalid_request" and "Invalid authorization code" response:-
Content-Type
header is set correctly in your POST request.urllib
or requests-oauthlib
, to rule out any issues with the requests
library.โ07-26-2024 01:41 AM
Followed this guide thoroughly https://docs.databricks.com/en/dev-tools/auth/oauth-u2m.html#manually-generate-and-use-access-tokens...
Unfortunately, no luck. Surprisingly, it worked well when was used in the month of March 2024.
โ07-26-2024 03:29 AM - edited โ07-26-2024 04:14 AM
Hi @MaheshMandlik ,
I've got it working. I recommend to split your code into two files, it's a lot easier to test. Once you obtained authorization token, you need to act fast if you want to generate access token, because authorization token are short-lived:
- get_authorization_token.py
- get_access_token.py
In get_authorization_token.py:
import uuid
import hashlib
import base64
import requests
import json
import webbrowser
# Generate a UUID.
uuid1 = uuid.uuid4()
# Convert the UUID to a string.
uuid_str1 = str(uuid1).upper()
# Create the code verifier.
code_verifier = uuid_str1 + "-" + uuid_str1
# Create the code challenge based on the code verifier.
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode('utf-8')
# Remove all padding from the code challenge.
code_challenge = code_challenge.replace('=', '')
print(f"code_verifier: {code_verifier}")
print(f"code_challenge: {code_challenge}")
account_id = "YOUR_ACCOUNT_ID"
redirect_url = "http://localhost:8020"
url1 = f"https://accounts.azuredatabricks.net/oidc/accounts/{account_id}/v1/authorize?client_id=databricks-cli&redirect_url={redirect_url}&response_type=code&state=helloworld&code_challenge={code_challenge}&code_challenge_method=S256&scope=all-apis+offline_access"
webbrowser.open(url1, new=2, autoraise=True)
In get_access_token.py:
import uuid
import hashlib
import base64
import requests
import json
import webbrowser
# Generate a UUID.
uuid1 = uuid.uuid4()
# Convert the UUID to a string.
uuid_str1 = str(uuid1).upper()
account_id = "YOUR_ACCOUNT_ID"
redirect_url = "http://localhost:8020"
authorization_code = "YOUR_AUTHORIZATION_CODE FROM FIRST FILE"
code_verifier = "CODE VERIFIER FROM FIRST FILE"
url = f"https://accounts.azuredatabricks.net/oidc/accounts/{account_id}/v1/token"
data = {
"client_id": "databricks-cli",
"grant_type": "authorization_code",
"scope": "all-apis offline_access",
"redirect_uri": redirect_url,
"code_verifier": code_verifier,
"code": authorization_code
}
response = requests.post(url, data=data)
print(response.status_code)
print(response.json())
โ07-26-2024 04:51 AM - edited โ07-26-2024 05:03 AM
@MaheshMandlik, probably forgot to mention, but splitting this code to two separate files helps to avoid generating new code_verifier by mistake.
โ07-26-2024 06:46 AM
@Slash Thank you for your help. Your solution has worked very well for me.
โ07-26-2024 07:25 AM - edited โ07-26-2024 08:52 AM
No problem, glad that I could help. You can also marked my answer as a solution to help community
Join a Regional User Group to connect with local Databricks users. Events will be happening in your city, and you wonโt want to miss the chance to attend and share knowledge.
If there isnโt a group near you, start one and help create a community that brings people together.
Request a New Group