I am currently trying to debug an Android App built around WebView. The development network environment that I am tasked to deal with (not my choice, it is an 'enterprisey' security decision) is WPA WiFi + proxy server + proxy authentication.
While the instructions on a very helpful previous answer were great, I'm trying to find a way to configure both proxy host:port and username:password.
My constraints are:
- Phone is not rooted - trying to reproduce a customer-reported bug, would rather not deviate from typical customer setup
- Running a Samsung Galaxy S on Froyo
- Built against 2.1
Android apps aren't my usual thing, again not my choice, so if I'm blatantly missing details, be nice ;)
With WebView android proxy configuration, for basic scheme preemptive proxy authentication,
Starting from Android 2.2, the extra header can be set for authentication. The following can add a header for webView
's http request:
public void loadUrl(WebView view, String url, String proxyUserName, String proxyPassword){
UsernamePasswordCredentials creds= new UsernamePasswordCredentials(proxyUserName, proxyPassword);
Header credHeader = BasicScheme.authenticate(creds, "UTF-8", true);
Map<String, String> header = new HashMap<String, String>();
header.put(credHeader.getName(), credHeader.getValue());
view.loadUrl(url, header);
}
For older version, the preemptive proxy authentication can be set on mProxyUserName
and mProxyPassword
in android.webkit.Network
by reflection:
public void loadUrl(WebView view, String url, String proxyUserName, String proxyPassword){
try{
Class networkClass = Class.forName("android.webkit.Network");
if (networkClass != null) {
Object networkObj = invokeMethod(networkClass, "getInstance", new Object[]{view.getContext()}, Context.class);
if (networkObj != null) {
Field mProxyUserName = obj.getClass().getDeclaredField("mProxyUserName");
mProxyUserName.setAccessible(true);mProxyUserName.set(networkObj, proxyUserName);
Field mProxyPassword = obj.getClass().getDeclaredField("mProxyPassword");
mProxyPassword.setAccessible(true);mProxyPassword.set(networkObj, proxyPassword);
}
}
}catch(Exception e){
e.printStackTrace();
}
view.loadUrl(url);
}
When you load a new url, both loadUrl()
must need to call again. That is very important.
Therefore, a custom WebViewClient
should be used to override shouldOverrideUrlLoading(WebView view, String url)
class ProxyAuthWebViewClient extends WebViewClient {
String proxyUserName;
String proxyPassword;
public ProxyAuthWebViewClient(String proxyUserName, String proxyPassword){
this.proxyUserName = proxyUserName;
this.proxyPassword = proxyPassword;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
loadUrl(view, url, proxyUserName, proxyPassword);
return true ;
}
}
And set the WebViewClient on your webView:
webView.setWebViewClient(new ProxyAuthWebViewClient("user", "password"));