I have researched and researched and researched this until I've gone grey and bald. How on earth do I get a webview to work for a site that needs http basic authentication over an https connection on api level 8+
I have the following code
String email = Util.getEmail(this);
String pwd = Util.getPassword(this);
webview.getSettings().setJavaScriptEnabled(true);
webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd);
// webview.setWebViewClient(new MobileWebViewClient(this));
webview.loadUrl(url);
As you can see I did have a web view client (Now commented out) that overrides the onReceivedHttpAuthRequest method which looks like this
@Override
public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm){
String email = Util.getEmail(wvContext);
String pwd = Util.getPassword(wvContext);
if(!pwd.equalsIgnoreCase("-1") && !pwd.equalsIgnoreCase("-1")){
handler.proceed(email, pwd);
}
}
This was used without the webview.setHttpAuthUsernamePassword and works fine except that it means 2 requests are issued to the website - The first gets a 401 and then the client kicks in with the authorisation stuff This is fine for a small amount of website traffic but halving the amount of traffic (currently averaging 49 requests p/m) is the name of the game right now!
I read that I can pre-emptively supply the credentials by using
webview.setHttpAuthUsernamePassword(Config.SERVER_BASE_URL, "Application", email, pwd);
However this just results in Http Basic: Access denied errors The server base url constant is the domain name for the site i.e. https://example.com (without the page) the actual url is https://example.com/some_pages . It makes no difference whether I use the full url or the domain. I have checked the realm and I have that correct and I have used just empty strings providing only email and password. Could this be something to do with the fact that the site is using https? My code seems to work fine on my dev box without https but that may be a red herring.!
The only stack overflow questions that seem to cover my requirements have not got accepted answers and the docs are no help that I can see.
I now have such a large dent in my head from banging it against a brick wall that I am thinking of getting a square hat.
Please if anyone can give me the solution to this I will be forever in your debt! I might even e-Mail you an KitKat
Source: Tips4all
This simple example abuses a page on HttpWatch since it's more fun with a working public example.
ReplyDeleteThe resource in question, https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?randomgarbage uses basic auth over HTTPS and can be loaded without authentication failure like this (tested using Android 2.3.7):
WebView v = ...; // Your webview goes here.
try {
HashMap<String, String> map = new HashMap<String, String>();
// This test service takes the username "httpwatch" and a random
// password. Repeating a password can lead to failure, so we create
// a decently random one using UUID.
String usernameRandomPassword = "httpwatch:" + UUID.randomUUID().toString();
String authorization = "Basic " + Base64.encodeToString(usernameRandomPassword.getBytes("UTF-8"), Base64.NO_WRAP);
map.put("Authorization", authorization);
v.loadUrl("https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?" + System.currentTimeMillis(), map);
} catch (UnsupportedEncodingException e) {}
This works on ICS and Gingerbread. Don't have access to anything older than that, but loadUrl(String, Map<String,String>) was introduced in API level 8, so I don't see why it shouldn't work for that to.
Clarification for Nappy:
To support authentication for subsequent requests you supply a WebViewClient and do the following:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url, <your map containing the Authorization header>);
return true;
}
});
It will work for https URL.In this if we are getting Untrusted_cer then we will ignore it
ReplyDeletewebview.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
super.onReceivedHttpAuthRequest(view, handler, host, realm);
}
@Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
if(error.getPrimaryError()==SslError.SSL_UNTRUSTED){
handler.proceed();
}else{
handler.proceed();
}
}
});
I have no idea about second problem