Selenium Chrome 60无头处理基本认证通过HTTPS进行SAML对话

时间:2017-07-28 13:04:41

标签: c# selenium-webdriver selenium-chromedriver http-basic-authentication

Chrome 59 removed support for https://user:password@example.com URLs

我有一个需要使用Chrome Version 60 on Windows in 'headless' mode

的C#selenium测试
ChromeOptions options = new ChromeOptions();
options.AddArgument("headless");
driver = new ChromeDriver(chrome, options);

以下是我尝试在Windows上处理的SAML身份验证所需对话框: Basic Auth Dialog

基于这里给出的答案:How to handle authentication popup with Selenium WebDriver using Java)我可以看到在FireFox中处理此问题的几种解决方法,但在无头模式下Chrome 60没有。

我在访问受测试的网址之前尝试了以下代码来访问带有凭据的网址(没有凭据)但是看起来有一个bug与Chrome 60.

goTo("http://user:password@localhost"); // Caches auth, but page itself is blocked
goTo("http://localhost"); // Uses cached auth, page renders fine
// Continue test as normal

我可以看到 Firefox 中的以下代码处理身份验证,对话框永远不会弹出:

FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.automatic-ntlm-auth.trusted-uris", "https://saml.domain.com");
profile.EnableNativeEvents = false;`

我已经尝试了第二种方法(using AutoIt)并且适用于Chrome 60但无头模式下在Chrome 60上工作。

//Use AutoIt to wait 4 seconds for the authentication required dialog to appear
au3.Sleep(4000);
//Use AutoIT to send in the credentials from app.config that are encrypted
au3.Send(USERNAME + "{TAB}" + PASSWORD + "{ENTER}");
//Refresh the page
driver.Navigate().Refresh();

我希望2017年有一个更好的解决方案,并且有一种方法可以在无头模式下使用Chrome 60,任何指针?

为了清楚起见:尝试使用embedded credentials将无法使用chrome v59 +,因为子资源请求将被阻止。

3 个答案:

答案 0 :(得分:1)

我知道这已经快一年了,但这正是我在类似情况下工作的结果。确实,身份验证弹出窗口已更改,ChromeDriver似乎不再支持它或http(s)://user:password@url.com方案,但是我发现here的解决方法似乎可以解决问题。它最初是为对代理系统进行身份验证而编写的,但可以进行修改以与任何身份验证系统一起使用。

基本上,您需要创建一个chrome扩展程序来处理在页面上输入登录详细信息。可以使用ChromeOptions.AddExtension(string FilePath)添加chrome扩展名,而扩展名只是具有manifest.json的zip文件和任何可以完成工作的代码文件。这是您需要的文件。

manifest.json

{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "Chrome Proxy",
    "permissions": [
        "proxy",
        "tabs",
        "unlimitedStorage",
        "storage",
        "<all_urls>",
        "webRequest",
        "webRequestBlocking"
    ],
    "background": {
        "scripts": ["background.js"]
    },
    "minimum_chrome_version":"22.0.0"
}

background.js

function callbackFn(details) {
    return {
        authCredentials: {
            username: "YOUR_PROXY_USERNAME",
            password: "YOUR_PROXY_PASSWORD"
        }
    };
}

chrome.webRequest.onAuthRequired.addListener(
    callbackFn,
    {urls: ["YOUR_WEBSITE_ADDRESS"]},
    ['blocking']
);

答案 1 :(得分:0)

也许您可以使用方法setRequestHeader使用XMLHttpRequest执行以前的连接,以便您可以指定身份验证标头。执行单个请求后,您将对所有其他类型的请求进行身份验证。更大的问题可能是XSS,根据您的情况,您可以解决它。

答案 2 :(得分:-1)

您可以使用“ MultiPass进行HTTP基本身份验证” Chrome扩展程序来处理此问题。

您可以通过GitHub MultiPass for HTTP basic authentication

(或)

从Chrome网上应用店下载扩展程序-MultiPass Chrome Extension

(或)

将扩展名下载为crx。您可以从chrome-extension-downloader

获取它作为crx

将扩展程序下载为crx文件后,将其配置为“测试/源”非常简单。

这可以使用Sample Basic Auth-Site进行测试。

public class ChromeAuthTest {

    WebDriver driver;

    public ChromeAuthTest() {
        System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
    }

    private void initDriver() {
        ChromeOptions cOptions = new ChromeOptions();
        cOptions.addExtensions(new File("MultiPass-for-HTTP-basic-authentication_v.crx"));
        driver = new ChromeDriver(cOptions);
        configureAuth(
                "https://the-internet.herokuapp.com/basic_auth",
                "admin",
                "admin");
    }

    private void configureAuth(String url, String username, String password) {
        driver.get("chrome-extension://enhldmjbphoeibbpdhmjkchohnidgnah/options.html");
        driver.findElement(By.id("url")).sendKeys(url);
        driver.findElement(By.id("username")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.className("credential-form-submit")).click();
    }

    public void doTest() {
        initDriver();
        driver.get("https://the-internet.herokuapp.com/basic_auth");
        System.out.println(driver.getTitle());
        driver.quit();
    }

    public static void main(String[] args) {
        new ChromeAuthTest().doTest();
    }
}
  

注意:这取自此Answer

希望这会有所帮助!