问题
I have a web page. When I open that web page first it ask for server authentication. After providing the server authentication it allows me to navigate the web site. I have to automate that web page but because of the server authentication I am unable to move forward. How I can handle this server authentication in Geb or Web Driver
回答1:
Try using this :
http://username:password@site.com/page
Instead of :
http://site.com/page
回答2:
This is called basic auth. So you can pass username and password in the address bar
http://user:password@example.com
Basic auth is not supported by WebDriver
回答3:
I couldn't have used this, as I have @ in my username (yeah, Microsoft account). That's why I decided to go for proxy solution that would intercept my requests and insert prepared Authorization header. And I wanted to use proxy directly in the test, so it is fully automated. Now the resulting code is rather rough, based on Browser.drive
and not any state of art Geb code, but I believe that if you know Geb, you can easily adapt it:
import geb.Browser
import geb.Configuration
import io.netty.handler.codec.http.DefaultHttpRequest
import io.netty.handler.codec.http.HttpObject
import io.netty.handler.codec.http.HttpRequest
import io.netty.handler.codec.http.HttpResponse
import org.littleshoot.proxy.HttpFilters
import org.littleshoot.proxy.HttpFiltersAdapter
import org.littleshoot.proxy.HttpFiltersSourceAdapter
import org.littleshoot.proxy.HttpProxyServer
import org.littleshoot.proxy.impl.DefaultHttpProxyServer
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxProfile
def baseUrl = System.getProperty("baseUrl", "http://localhost/app/")
// LittleProxy setup
def proxyPort = 8181
HttpProxyServer server = DefaultHttpProxyServer.bootstrap()
.withPort(proxyPort)
.withFiltersSource(
new HttpFiltersSourceAdapter() {
@Override
HttpFilters filterRequest(HttpRequest originalRequest) {
return new HttpFiltersAdapter(originalRequest) {
@Override
HttpResponse requestPre(HttpObject httpObject) {
if (httpObject instanceof DefaultHttpRequest) {
if (httpObject.getUri().startsWith(baseUrl)) {
if (httpObject.headers().contains("Authorization")) {
println "Already contains the Authorization header: " + httpObject.getUri()
} else {
println "Adding Authorization header to request: " + httpObject.getUri()
httpObject.headers().add("Authorization", "Basic " + System.getProperty("basicAuth"))
}
} else {
println "Ignoring request: " + httpObject.getUri()
}
} else {
println "Ignoring event: " + httpObject
}
return null
}
}
}
})
.start();
println "Base URL: " + baseUrl
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.proxy.http", "localhost");
profile.setPreference("network.proxy.http_port", proxyPort);
// to force proxy for localhost or 127.0.0.1 too
profile.setPreference("network.proxy.no_proxies_on", "");
// http://kb.mozillazine.org/Network.proxy.type
// 1 = manual proxy configuration; default 5 would use system settings
profile.setPreference("network.proxy.type", 1);
profile.setPreference("browser.fixup.alternate.enabled", false);
def configuration = new Configuration()
def driver = new FirefoxDriver(profile)
configuration.setDriver(driver)
Browser.drive(configuration, {
go baseUrl
def navigator = $("#app-title")
assert navigator.getAttribute("title") == "App title"
})
driver.close()
server.stop()
First it starts proxy - based on https://github.com/adamfisk/LittleProxy
Then it setups Firefox profile for proxy. Some of the setup is related to localhost
usage but it will not hurt if you use any other hostname.
Finally we start the test, providing the configuration into the drive(...)
call.
I yet have to get more experiences with the little proxy, how stable it is, etc. But for this easy case it works just fine. It is important to intercept only requests for baseUrl
, because Firefox may call google search for instance - and you don't want to send your auth hash there (as it is easy to reverse). That's also why I provide it in the JVM argument: -DbaseUrl=http://localhost/finrisk -DbasicAuth=xxx...allTheWayToEqualSing=
Obviously, it is for Firefox now, but I guess it should be possible to adapt it for other browsers, if you can set up their proxy settings.
来源:https://stackoverflow.com/questions/19444161/how-to-handle-server-authentication-using-geb-webdriver