JSL / JMP 17:OAuth 顯然產生了無效請求我目前正在嘗試獲取 OAuth2 令牌來對外部服務(Snowflake 資料庫)進行身份驗證,但是遇到了一些問題。
根據文檔,這應該可以工作:
oauth2_token = New OAuth2 Token(<BR /> User( username ),<BR /> Password( password),<BR /> Client ID( client_id ),<BR /> Client Secret( client_secret ),<BR /> Token URL( "http://localhost:8008" ),<BR /> Grant Type("password"),<BR /> Scope("session:role-any")<BR />);
但是,每當我執行這個程式時,我都會收到一個 HTTP/1.1 400 Bad Request INVALID_REQUEST:INVALID_REQUESTDESCRIPTION
為了調試這個問題,我啟動了一個本地運行的 HTTP 回顯伺服器,並從 Python(工作代碼,已通過真實的 OAuth2 伺服器驗證)和 JMP 發送請求,然後我得到了以下回應:
Python
127.0.0.1 - - [05/Feb/2025 13:36:00] "POST / HTTP/1.1" 200 -
主機:localhost:8008
用戶代理:python-requests/2.32.3
接受編碼:gzip,deflate
接受: */*
連結:保持活動
內容長度:91
內容類型:application/x-www-form-urlencoded
授權:基本=
grant_type=密碼&使用者名稱= &密碼= &scope=session%3Arole-any
JMP17
127.0.0.1 - - [05/Feb/2025 13:36:56] "POST / HTTP/1.1" 200 -
主機:localhost:8008
使用者代理:libcurl-agent/1.0(Windows NT 10.0.22631;x64)
接受: */*
內容長度:102
內容類型:application/x-www-form-urlencoded
客戶端ID= &redirect_uri=&response_type=token&範圍=&狀態=
如您所見,沒有授權標頭,且大多數請求參數(授予類型、使用者名稱、密碼、範圍)都缺失。
對我來說,JMP 似乎產生了一個虛假請求,因此與伺服器的通訊失敗。這個假設正確嗎?還是我做錯了什麼?
任何幫助都將非常感激。
親切的問候
坦白
自動化和腳本回覆:JSL / JMP 17:OAuth 顯然產生了無效請求@bryan_boone
不確定這些連結是否有用,但使用 HTTP 請求將 Google Drive 與 JMP 整合可能會提供一些想法。也請查看腳本索引中的獲取授權標頭 + 新 OAuth2(bryan 在這裡提到了這些https://community.jmp.com/t5/Discussions/Open-file-from-private-github-repository-authentication-needed/mp/777304/highlight/trueM95860 M95860)。 JSL 語法參考中還有更多文檔,但不知道是否有幫助https://www.jmp.com/support/help/en/18.1/#page/jmp/utility-functions.shtml?os=win&source=application#ww7957559
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求是的,
新 OAuth2
是正確的做法。我查看是否可以將 New OAuth2 Token 作為它的別名。
如果沒有,我將棄用新的 OAuth2 令牌。
新的 OAuth2 為您完成所有瀏覽器握手。
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求謝謝,新的 OAuth2() 看起來好多了。我成功地透過「客戶端憑證」流程取得了刷新令牌。
然而,我正在努力讓密碼流程正常運作。我目前的程式碼如下:
client_id = "<REDACTED>";
client_secret = "<REDACTED>";
token_url = "https://someurl/token";
auth_url = "https://someurl/auth";
username = "<REDACTED>";
password = "<REDACTED>";
grant_type = "password";
scope = "session:role-any";
auth_fields = [=> ];
token_fields = [=> ];
oauth2 = New OAuth2();
oauth2 << Grant Type( "Password" );
oauth2 << Auth URL( auth_url );
oauth2 << Token URL( token_url );
oauth2 << Username(username);
oauth2 << Password(password);
auth_fields["scope"] = scope;
auth_fields["client_id"] = client_id;
token_fields["client_secret"] = client_secret;
oauth2 << Auth Fields( auth_fields );
oauth2 << Token Fields( token_fields );</REDACTED></REDACTED></REDACTED></REDACTED>但是,這會導致 HTTP/1.1 401 未授權。
為了進行比較,這裡有一個 Python 中可行的範例:
def get_token(username: str, password: str, client_secret: str) -> str:
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, client_secret)
post_data = {
"grant_type": "password",
"username": username,
"password": password,
"scope": "session:role-any",
}
response = requests.post(TOKEN_URL, auth=client_auth, data=post_data)
token_json = response.json()
print(f"Got token: {token_json}")
return token_json["access_token"]我猜測,由於某種原因,JMP 沒有使用 client_id / client_secret 建立 HTTP Basic 驗證。我做錯什麼了?
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求我認為你正在談論的是:
https://oauth.net/2/grant-types/password/
這次討論(關於參考)表明已經遠離了這一點。
您可能可以使用 HTTPRequest(無需 New OAuth2)完成所有操作,因為無需使用密碼授予類型進行提示(即,它直接針對令牌 URL)
我認為等效的 JSL(對於 python)看起來像這樣,但我無法測試它。
client_id = "<REDACTED>";
client_secret = "<REDACTED>";
token_url = "https://someurl/token";
username = "<REDACTED>";
password = "<REDACTED>";
grant_type = "password";
scope = "session:role-any";
payload =[=>];
payload["grant_type"] = "password";
payload["username"] = username;
payload["password"] = password;
payload["scope"] = scope;
request = New HTTP Request(
URL(token_url),
Username(client_id),
Passwordlient_id),
JSON(payload)
);
data = request << Send();
json = ParseJSON(data);</REDACTED></REDACTED></REDACTED></REDACTED>
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求經過一番擺弄,我讓它工作了;根據你的建議,主要做了以下修改:
- 包括基本身份驗證
- 使用表單編碼而不是 JSON(雖然不能 100% 確定為什麼 JSON 不起作用)
工作範例:
client_id = "<REDACTED>";
client_secret = "<REDACTED>";
token_url = "https://someurl/token";
username = "<REDACTED>";
password = "<REDACTED>";
grant_type = "password";
scope = "session:role-any";
request = New HTTP Request(
Method("POST"),
URL(token_url),
Username(client_id),
Password(client_secret),
Form(
Fields([[
"grant_type" => grant_type,
"username" => username,
"password" => password,
"scope" => scope
]]
)
)
);
request << Authentication Method( "BASIC" );
data = request << Send();
json = ParseJSON(data);</REDACTED></REDACTED></REDACTED></REDACTED>
就目前而言,這是可以的(我們使用技術用戶,因此不需要獲取用戶的個人密碼),但我們肯定會研究更安全的方法。
非常感謝您的幫忙!
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求很棒的發現!我不太確定我引入了哪 17 種授權方法(可能是維護?)
回覆:JSL / JMP 17:OAuth 顯然產生了無效請求小小的(但重要的)更正:看來我的方法只適用於 JMP 18,而不適用於 JMP 17。
顯然,「授權方法」僅在 JMP 18 中引入。
存取或評估‘身份驗證方法’時出現無法識別的訊息,身份驗證方法(“BASIC”)/*###*/
我重新檢查了文件:
- JMP 17 文件中完全沒有提及“身份驗證方法”
- JMP 18 文件包含PI 呼叫中「驗證方法」的範例
(我之前沒有註意到這一點,因為顯然,我的 JMP 18 測試中的令牌存儲在 JMP 檔案/資料表中,因此,JMP 17 很樂意使用舊令牌,即使它自己嘗試獲取新令牌失敗了)