【问题标题】:getting json with python requests behind microsoft authentication使用 Microsoft 身份验证后面的 python 请求获取 json
【发布时间】:2021-08-06 06:04:57
【问题描述】:

我正在尝试从使用 Microsoft 身份验证的 Web 服务访问一些 json 数据

我有一个可以在浏览器中登录的用户名和密码。

如果我将登录数据作为身份验证传递,则响应是一堵难以辨认的 html 和 js 脚本墙

s = requests.Session()
login_data =  {'login':username, 'loginfmt':username, 'passwd':pw}
r=s.post(login_url,auth=login_data)
r= s.get(json_url)
print(r.text)

我尝试从通过浏览器登录时复制网络数据、cookies 和标头,但使用这种方法我也只能得到一堵难以辨认的 html 和 js 墙

cookies = {
    'x-ms-gateway-slice': 'estsfd',
    'stsservicecookie': 'estsfd',
    'AADSSO': 'NA|NoExtension',
    'buid': '...',
    'fpc': '...',
    'esctx': '...',
    'brcap': '0',
    'clrc': '...',
    'wlidperf': '...',
}

headers = {
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
    'sec-ch-ua-mobile': '?0',
    'Upgrade-Insecure-Requests': '1',
    'Origin': 'https://login.microsoftonline.com',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document',
    'Referer': 'https://login.microsoftonline.com/.../oauth2/authorize?client_id=...&redirect_uri=...&response_type=id_token&scope=...&x-client-ver=6.8.0.0&sso_reload=true',
    'Accept-Language': 'en-US,en;q=0.9',
}

data = {
  'i13': '0',
  'login': '',
  'loginfmt': '',
  'type': '11',
  'LoginOptions': '3',
  'lrt': '',
  'lrtPartition': '',
  'hisRegion': '',
  'hisScaleUnit': '',
  'passwd': '',
  'ps': '2',
  'psRNGCDefaultType': '',
  'psRNGCEntropy': '',
  'psRNGCSLK': '',
  'canary': '...',
  'ctx': '...',
  'hpgrequestid': '...',
  'flowToken': '...',
  'PPSX': '',
  'NewUser': '1',
  'FoundMSAs': '',
  'fspost': '0',
  'i21': '0',
  'CookieDisclosure': '0',
  'IsFidoSupported': '1',
  'isSignupPost': '0',
  'i2': '1',
  'i17': '',
  'i18': '',
  'i19': '...'
}
s = requests.Session()
r=s.post(login_url, headers=headers, cookies=cookies, data=data)
r= s.get(json_url)
print(r.text)

这些数据,即 canary、ctx、hprequestid 和 flow 令牌从 post 到 post 会发生变化

唯一可行的方法是在身份验证后获取 cookie

cookies = {
    'ARRAffinity': '...',
    'ARRAffinitySameSite': '...',
    '.AspNetCore.AzureADCookie': 'chunks-2',
    '.AspNetCore.AzureADCookieC1': '...',
    '.AspNetCore.AzureADCookieC2': '...',
}
s = requests.Session()
r= s.get(json_url,cookies=cookies)
print(r.text)

但是cookie会在一段时间后过期,每次手动将cookie复制到脚本中并不是超级可持续的。

我已尝试阅读 Kerberos 和 msal 模块,但找不到任何关于从使用 Microsoft 身份验证的 Web 服务检索数据的信息,只有如何为您自己的 Web 服务设置 ms 身份验证。

【问题讨论】:

    标签: python python-3.x python-requests azure-active-directory


    【解决方案1】:

    使用请求时,您需要 html 在某处提供的一堆数据,我应该通过 canary ctx 和 hprquestid 随每个请求的更改而了解这一点。 这个问题和答案非常一致:Login to Facebook using python requests

    我最终做的是使用 selenium 登录并获取 json。

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    import time
    import datetime, json
    
    browser = webdriver.Firefox()
    browser.get(json_url)
    elem = browser.find_element_by_name('loginfmt')
    elem.send_keys(username + Keys.RETURN)
    
    time.sleep(1)
    elem = browser.find_element_by_name('passwd')
    elem.send_keys(pw + Keys.RETURN)
    
    time.sleep(1)
    browser.get(json_url)
    
    elem = browser.find_element_by_id('json')
    json_data_rettid = json.loads(elem.get_attribute('innerHTML'))
    
    browser.quit()
    

    (我知道我应该使用 build in selenium 等待功能,但在编写此代码时我没有)

    注意:我发现 chrome 驱动程序很难正常工作,所以我推荐使用 firefox 驱动程序

    【讨论】:

      猜你喜欢
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      相关资源
      最近更新 更多