使用 login.microsoftonline.com 验证请求会话

问题描述 投票:0回答:2

我正在尝试对 login.microsoftonline.com 进行身份验证,以访问隐藏在 SSO 后面的资源。我需要获取 SAML 响应以发布到 SSO,以便我进行身份验证。唯一的问题是我无法通过微软进行身份验证,因为流令牌和请求不会加载流令牌,因为它需要使用 JavaScript 加载。如何进行身份验证?

python python-3.x request saml
2个回答
1
投票

我想说答案很简单,但需要一些工作,而且我不确定这在不同的环境中如何工作,但这是我为我所做的。

  1. 创建一个类并初始化动态信息。这是我的
class Microsoft:
    # TODO: Add MFA option
    def __init__(self, username: str, password: str):
        self.sess = requests.Session()
        self.username = username
        self.password = password
        self.base = "https://login.microsoftonline.com/"
        self.tenant = "redacted/"
        self.url = ""
  1. 使用requests_html HTMLSession和bs4 beautifuSoup(此处为bs)来获取流令牌
# used to return values of input fields rendered
    def get_html_name_value(self, html: str, name: str) -> str:
        return bs(html, "lxml").find("input", {"name": name}).get("value")

# get redirected to obtain flow token with appropriate SAML
    def _get_tokens(self):
        session = HTMLSession()
        # update this
        resp = session.get(
            "https://sso.redacted.com/cas/clientredirect?client_name=SAML2Client45&"
            + "service=https://full/path/to/service_behind_sso"
        )
        self.url = resp.url
        resp.html.render()
        html = resp.html.html
        data = {
            "flowToken": bs(resp.html.html, "lxml")
            .find(id="i0327")
            .get("value"),
            "ctx": self.get_html_name_value(html, "ctx"),
            "canary": self.get_html_name_value(html, "canary"),
            "hpgrequestid": self.get_html_name_value(html, "hpgrequestid"),
        }
        return session, data

  1. 发布数据以获取 saml 令牌。当您发布给定的数据时,它将返回一个需要发布的 html 表单。
    def _get_saml_tokens(self):
        sess, payload = self._get_tokens()
        payload["login"] = self.username
        payload["loginfmt"] = self.username
        payload["passwd"] = self.password
        headers = {
            "Host": "login.microsoftonline.com",
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:88.0) Gecko/20100101"
            + " Firefox/88.0",
            "Referer": self.url,
            "Origin": "https://login.microsoftonline.com",
        }
        html = sess.post(
            self.base + self.tenant + "/login",
            data=payload,
            headers=headers,
        ).text

        data = {
            "SAMLResponse": self.get_html_name_value(html, "SAMLResponse"),
            "RelayState": self.get_html_name_value(html, "RelayState"),
        }
        return sess, data

  1. 最后一步是发布 saml 响应和中继状态,以便您可以访问服务

    def _login(self):
        sess, payload = self._get_saml_tokens()

        return sess.post(
            "https://sso.redacted.com/cas/login?client_name=SAML2Client45",
            data=payload,
        )

从这里您可以提取 cookie 并将它们放入正常的请求会话中或继续在 HTMLSession() 中操作

您可以对其他资源使用令牌身份验证执行类似的操作,但我还不需要访问它,也没有编写代码。

关键是更改第 2 步中的初始请求,以便第 3 步将收到令牌,然后在那里发布正确的身份验证。希望大家能够根据需要进行调整


0
投票

如果其他人正在寻找不需要浏览器的解决方案(requests-html/selenium),这里有一个适合我的仅请求解决方案:https://github.com/ownjoo-org/entra_saml_logon

© www.soinside.com 2019 - 2024. All rights reserved.