2016-09-20 19 views
1

我正在研究一種Python中的報告工具,它將從ServiceNow的JSON Web服務中獲取數據。我們的ServiceNow實例使用普通的用戶id/pw認證和SHA-1認證。我的問題是,我無法使用我的腳本訪問JSON Web服務結果頁面(https://servicenowserver.com/table.do?JSONv2&sysparm_query=active=true^number = 12345678)從那裏獲取數據。我可以使用我的腳本登錄到主頁面(https://servicenowserver.com),它進行身份驗證,並提供HTTP 200,但是當我調用JSON webservice頁面時,會給我HTTP 401(未授權)。ServiceNow JSON Web服務的Python身份驗證

一旦我登錄通過瀏覽器的ServiceNow和我的會話開始我可以調用JSON服務的新選項卡上的它讓我看到的結果,但這不是我的Python腳本工作。我試圖使用urllib3requests庫與一個會話參數保持會話打開,但它也不工作。我認爲我的腳本在我打電話給主頁後立即關閉會話。我試圖通過餅乾,沒有任何運氣。

長話短說:它從我的瀏覽器的工作原理,但它沒有,如果我使用Python腳本。

你知道我應該如何進行身份驗證才能獲得JSON結果?或者至少如果有人能指導我,我怎麼能得到更詳細的調試?

下面你可以找到,我已經嘗試過的解決方案之一:

import requests 

s = requests.session() 
s.auth = ('user', 'password') 
s.verify = 'sn.cer' 

r = s.get('https://servicenowserver.com', verify=True) 
print (r) # This gives HTTP 200 

r2 = s.get ('https://servicenowserver.com/table.do?JSONv2&sysparm_query=active=true^number=12345678', verify=True, cookies=s.cookies) 
print (r2) # This gives HTTP 401 
+0

您正在進行身份驗證的用戶是否具有soap_query角色? – Hoopdady

+0

@Hoopdady有什麼方法可以檢查作爲普通用戶嗎?它從我的瀏覽器工作,並給我的JSON結果,所以我認爲我有適當的訪問。 – g0m3z

+0

如果您的管理員設置正確,我不相信您將能夠檢查它。可以在左側的導航欄中輸入「user」,看看用戶部分是否出現。另外,它可能是rest_service角色,我不記得了。 – Hoopdady

回答

3

我會設法找出解決辦法,所以我在這裏發佈它。我要在這裏發佈的並不是我的問題的確切解決方案,而是理解和檢查如何跟蹤身份驗證的一般方法。我使用這種技術來跟蹤我的情況下的登錄過程。

在我的情況的ServiceNow使用基於Cookie的身份驗證和傳遞信息的來回中4頁。第一頁生成一個名爲NSC的ID,並將其作爲一個cookie傳遞到第二頁,以生成另一個名爲SMSESSION ID的ID,然後將其傳遞到cookie中的第三頁和NSC ID以生成最終的JSESSION ID。最後,流程將所有先前生成的3個ID傳遞到cookie中的登錄頁面以驗證會話。

我使用Google Developer Tools來弄清楚這一點。我建議你做的是以下幾點。

1)轉到谷歌瀏覽器的登錄頁面,你想傳遞和等待網站加載。不要登錄。

2.)打開開發工具(右擊,檢查元素菜單選項)。如果你熟悉其他瀏覽器的開發能力,那也很好。

3)進入開發工具的應用程序選項卡,單擊清除存儲在左側的菜單欄。這將清除爲該頁面存儲的所有數據。您可以通過清除Cookie和其他數據在Chrome的設置菜單中執行相同的操作。這需要清除頁面上已經發生的所有歷史步驟,以免造成任何混淆。

4)一旦完成去開發工具的網絡選項卡並單擊(旁邊的錄製按鈕)清除菜單選項。這將清除網絡日誌歷史記錄。

5.)下一步勾選網絡選項卡上的保留日誌複選框。這將使我們能夠跟蹤每一個步驟,即使在任何重定向的情況下。如果您不勾選此選項,則您的登錄頁面將您重定向到其他地方後,您將丟失所有數據,因爲它會清除網絡日誌。

6.)現在當我們刪除所有歷史數據並設置所有內容時,我們可以開始調查。使用您的用戶名和密碼登錄到頁面,並保持開發工具處於打開狀態,以便您可以查看所有網絡請求。等到登錄過程結束後,開始逐個檢查網絡日誌條目。

7.)您將看到一些GET和POST請求。這是您的登錄流程。通過雙擊打開第一個。它將向您顯示如(常規,響應標題,請求標題,查詢參數,表單數據等)部分組織的信息。這是在Web服務器和客戶端(您的機器)之間發生的信息交換。您需要對您的腳本進行模擬。這意味着您在「請求標題」部分中看到的任何內容都需要與您的腳本完全相同。這樣你將得到相同的響應頭,你可以從那裏獲取所有需要向前移動的信息。

讓我告訴你和例子。

在我的第一個POST請求我可以看到在網絡日誌中的以下內容:

General 
Request URL:https://mysnserver.net/siteminderagent/forms/dssologinprod.fcc?TYPE=33554433&REALMOID=06-0cffd45f-7ca7-106f-bbab-84fb3af10000&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=-SM-28THtkr3KQi%2fJmb193GjY0nVjpKo6ULc%2fJNV5hRyjzC17qWZfgyVPkR%2f7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3&TARGET=-SM-%2f 
Request Method:POST 
Status Code:302 Found 
Remote Address:1.1.1.196:443 

Response Headers 
Cache-Control:no-store 
Connection:Keep-Alive 
Content-Length:1541 
Content-Type:text/html; charset=iso-8859-1 
Date:Wed, 21 Sep 2016 19:11:46 GMT 
Keep-Alive:timeout=5, max=496 
Location:https://anothersite.com/SmMakeCookie.ccc?SMSESSION=-SM-w0Gp2DpiPEG&PERSIST=0&TARGET=-SM-https%3a%2f%2fservicemanagement%2net%2f 
Set-Cookie:SMSESSION=w0Gp2DpiPEGPrLepzXds9qUTVER/Xl75WO36n37IxRpLaE6dwQPwN2+iaNn4rQZODb+65k2Gy9fggnKU04I7rSU6; path=/; domain=.mysnserver.net; secure 
Set-Cookie:SMIDENTITY=EoIkGNtD3Y+FBWumdJuml3J78o61Qtc07b73XmqEeze; path=/; domain=.mysnserver.net; secure 
Set-Cookie:NSC_1.1.1.196-443-C72169=ffffffffaaa3746145525d5f4f58455e445a4a4253a5;expires=Wed, 21-Sep-2016 21:11:47 GMT;path=/;secure;httponly 
Set-Cookie:SMTRYNO=; expires=Fri, 25 Mar 2016 19:11:46 GMT; path=/; domain=.mysnserver.net; secure 

Request Headers 
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
Accept-Encoding:gzip, deflate, br 
Accept-Language:en-US,en;q=0.8 
Cache-Control:max-age=0 
Connection:keep-alive 
Content-Length:238 
Content-Type:application/x-www-form-urlencoded 
Host:mysnserver.net 
Origin:https://mysnserver.net 
Referer:https://anothersite.net/forms/dssologinprod.fcc?TYPE=33554433&REALMOID=06-0cffd45f-7ca7-106f-bbab-84fb3af10000&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=-SM-28THtkr3KQi%2fJmb193GjY0nVjpKo6ULc%2fJNV5hRyjzC17qWZfgyVPkR%2f7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3&TARGET=-SM-%2f 
Upgrade-Insecure-Requests:1 
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 

Query String Parameters 
TYPE:33554433 
REALMOID:06-0cffd45f-7ca7-106f-bbab-84fb3af10000 
GUID: 
SMAUTHREASON:0 
METHOD:GET 
SMAGENTNAME:-SM-28THtkr3KQi/Jmb193GjY0nVjpKo6ULc/JNV5hRyjzC17qWZfgyVPkR/7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3 
TARGET:-SM-/ 

Form Data 
SMENC:ISO-8859-1 
SMLOCALE:US-EN 
target:/ 
smquerydata: 
smauthreason:0 
smagentname:28THtkr3KQi/Jmb193GjY0nVjpKo6ULc/JNV5hRyjzC17qWZfgyVPkR/7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3 
postpreservationdata: 
USER:my_userid 
PASSWORD:my_password 

無論你可以在請求頭段看到,需要被傳遞到第一URL獲得響應頭信息。如果您在響應頭中看到我已收到服務器提供的多個ID。這意味着我需要在Python中準備我的第一個請求,以傳遞我在請求頭中的相同信息。像這樣:

auth_url1 = 'https://mysnserver.net/siteminderagent/forms/dssologinprod.fcc?TYPE=33554433&REALMOID=06-0cffd45f-7ca7-106f-bbab-84fb3af10000&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=-SM-28THtkr3KQi%2fJmb193GjY0nVjpKo6ULc%2fJNV5hRyjzC17qWZfgyVPkR%2f7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3&TARGET=-SM-%2f' 

# Initiating session 
s = requests.session() 

request_header_1 = { 
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 
    'Accept-Encoding':'gzip, deflate, br', 
    'Accept-Language':'en-US,en;q=0.8', 
    'Cache-Control':'max-age=0', 
    'Connection':'keep-alive', 
    'Content-Length':'238', 
    'Content-Type':'application/x-www-form-urlencoded', 
    'Host':'mysnserver.net', 
    'Origin':'https://mysnserver.net', 
    'Referer':'https:///anothersite.net/forms/dssologinprod.fcc?TYPE=33554433&REALMOID=06-0cffd45f-7ca7-106f-bbab-84fb3af10000&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=-SM-28THtkr3KQi%2fJmb193GjY0nVjpKo6ULc%2fJNV5hRyjzC17qWZfgyVPkR%2f7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3&TARGET=-SM-%2f', 
    'Upgrade-Insecure-Requests':'1', 
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36' 
} 

form_data_1 = { 
    'SMENC':'ISO-8859-1', 
    'SMLOCALE':'US-EN', 
    'target':'/', 
    'smquerydata':'', 
    'smauthreason':'0', 
    'smagentname':'28THtkr3KQi/Jmb193GjY0nVjpKo6ULc/JNV5hRyjzC17qWZfgyVPkR/7EAWoDVu3Gd3y3kTm3N2p0B8KVp0Hixjin0ZsDZ3', 
    'postpreservationdata':'', 
    'USER':'my_userid', #<----- Put your user ID here 
    'PASSWORD':'my_password' #<----- Put your password here 
} 
r = s.post(auth_url1, headers=request_header_1, data=form_data_1, verify=False, allow_redirects=False) 

# Get NSC ID from the response header which needs to be passed over in the 3rd request 
nsc_id = r.cookies.keys()[2] + "=" + r.cookies.values()[2] 

就是這樣。如果你有更多的重定向,你需要遵循相同的過程,直到你通過最後一頁並且你的會話進行了認證。在此之後,您可以使用您收集的cookie信息來驗證所有即將到來的請求。正如你所看到的,我已經發起了一個s = requests.session()命令的會話,我可以使用它來提交我的所有請求,而無需傳遞我的用戶ID和密碼來請求所有請求。當你需要發送一個GET並且你需要發送一個POST請求的時候要小心。您可以在標題的「常規信息」部分查看此信息。

一個更重要的說明。如果您的網站上有重定向,請在requests中使用allow_redirects=False。通過這種方式,您可以確保您的請求不會被重定向到其他站點,您將得到正確的響應頭信息。