Python 请求 - SAML 登录重定向

Python Requests - SAML Login Redirect

我正在尝试从这个 URL 登录网站:“https://pollev.com/login". Since I'm using a school email, the portal redirects to the school's login portal and uses that portal to authenticate the login. It shows up when you type in a uw.edu email (example: myname@uw.edu). After logging in, UW sends a POST request callback to https://www.polleverywhere.com/auth/washington/callback with a SAMLResponse header like this。我想我需要从 pollev 的登录页面模拟 GET 请求,然后发送登录信息 headers 到 UW 登录页面,但我现在正在做的事情不起作用。

这是我的代码:

import requests

with requests.session() as s:
     header_data = {
    'user - agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                    '(KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
    'referer': 'https://pollev.com/login'
    }
    login_data = {
    'j_username' : 'username',
    'j_password' : 'password',
    '_eventId_proceed' : 'Sign in'
    }

    r = s.get('https://idp.u.washington.edu/idp/profile/SAML2/Redirect/SSO?execution=e2s1',
          headers=header_data, data=login_data)
    print(r.text)

现在,r.text 显示了一个 NoSuchFlowExecutionException html 页面。我错过了什么?登录该网站通常需要登录名、密码、引荐来源网址和 X-CSRF 令牌,我可以做到这一点,但我不知道如何导航重定向以进行身份​​验证。

你不会成功伪造 SAML2 SSO。 UW 的身份提供者 (IdP) 希望支持来自服务提供者 (SP) polleverywhere.com 的身份验证请求。其中一部分是验证请求实际上来自 polleverywhere。这可能很简单,需要来自 polleverywhere 的 SSL 连接,也可能很复杂,需要加密和签名的身份验证请求。由于您没有这些凭据,因此生成的响应将不可读。 SP 已向 IdP 注册。

现在,可能 有一种不同的方式来登录 polleverywhere -- 不同的 URL 不会触发 SSO 请求,但可能会受到网络限制或需要其他困难的身份验证。

老问题,但我有几乎相同的需求并继续解决直到我解决它。就我而言,可能仍然是 OP 的情况,我拥有所需的凭据。我确信这可以变得更高效/pythonic 并且非常感谢这些提示/更正。

import re
import requests

# start HTTP request session
s = requests.Session()

# Prepare for first request - This is the ultimate target URL
url1 = '/URL/needing/shibbolethSAML/authentication'
header_data = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}

# Make first request
r1 = s.get(url1, headers = header_data)

# Prepare for second request - extract URL action for next POST from response, append header, and add login credentials
ss1 = re.search('action="', r1.text)
ss2 = re.search('" autocomplete', r1.text)
url2 = 'https://idp.u.washington.edu' + r1.text[ss1.span(0)[1]:ss2.span(0)[0]]
header_data.update({'Accept-Encoding': 'gzip, deflate, br', 'Content-Type': 'application/x-www-form-urlencoded'})
cred = {'j_username': 'username', 'j_password':'password', '_eventId_proceed' : 'Sign in'}

# Make second request
r2 = s.post(url2, data = cred)

# Prepare for third request - format and extract URL, RelayState, and SAMLResponse
ss3 = re.search('<form action="',r2.text) # expect only one instance of this pattern in string
ss4 = re.search('" method="post">',r2.text) # expect only one instance of this pattern in string
url3 = r2.text[ss3.span(0)[1]:ss4.span(0)[0]].replace('&#x3a;',':').replace('&#x2f;','/')

ss4 = re.search('name="RelayState" value="', r2.text) # expect only one instance of this pattern in string
ss5 = re.search('"/>', r2.text)
relaystate_value = r2.text[ss4.span(0)[1]:ss5.span(0)[0]].replace('&#x3a;',':')

ss6 = re.search('name="SAMLResponse" value="', r2.text)
ss7 = [m.span for m in re.finditer('"/>',r2.text)] # expect multiple matches with the second match being desired
saml_value = r2.text[ss6.span(0)[1]:ss7[1](0)[0]]

data = {'RelayState': relaystate_value, 'SAMLResponse': [saml_value, 'Continue']}
header_data.update({'Host': 'training.ehs.washington.edu', 'Referer': 'https://idp.u.washington.edu/', 'Connection': 'keep-alive'})

# Make third request
r3 = s.post(url3, headers=header_data, data = data)

# You should now be at the intended URL