I'm trying to load an SSL page with basic auth in a webview, but even though i run proceed() in onReceivedSslError and usr/pwd is correct I can't get past onReceivedHttpAuthRequest. If I remove the haveAuthenticated check in the code below it just loops endlessly with auth requests, like if the credentials were wrong. Seems like it won't accept the certificate when trying to authenticate.
Adding the basic auth header didn't change anything, any other way to get around this?
package com.my.package;
import java.util.HashMap;
import java.util.Map;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewActivity extends Activity {
public final static String USERNAME = "com.my.package.USERNAME";
@SuppressLint("SetJavaScriptEnabled")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Activity thisActivity = this;
final MainActivity mainActivity = new MainActivity();
// Get usr + pwd
Intent intent = getIntent();
final String username = intent.getStringExtra(MainActivity.USERNAME);
final String password = intent.getStringExtra(MainActivity.PASSWORD);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Webview
setContentView(R.layout.activity_webview);
WebView webview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
// SSL and authentication
webview.setWebViewClient(new WebViewClient() {
Boolean haveAuthenticated = false;
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Log.d(thisActivity.getLocalClassName(), "Error " + description);
}
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
Log.d(thisActivity.getLocalClassName(), "Auth " + handler.obtainMessage());
if (!haveAuthenticated) {
Log.d(thisActivity.getLocalClassName(), "!haveAuthenticated/" + handler.obtainMessage());
haveAuthenticated = true;
handler.proceed(username, password);
} else {
Log.d(thisActivity.getLocalClassName(), "haveAuthenticated/" + handler.obtainMessage());
haveAuthenticated = false;
setResult(401, mainActivity.getIntent());
thisActivity.finish();
}
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
Log.d(thisActivity.getLocalClassName(), "SSL Error " + error.toString());
handler.proceed();
}
// Trying basic auth headers
String up = username + ":" +password;
String authEncoded = Base64.encodeToString(up.getBytes(), 0);
String authHeader = "Basic " + authEncoded;
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", authHeader);
webview.loadUrl(getString(R.string.webview_url), headers);
}
}
The weird thing is that it works on some devices but not all, e.g. not on Asus Padfone 2 with the following logs.
03-25 08:42:52.363: D/WebViewActivity(30030): SSL primary error: 3 certificate: Issued to: CN=*.company.com,OU=IT,O=COMPANY ASA,L=Here,ST=Norway,C=NO,2.5.4.5=#1320476557596744525532556f634c42487675656f484b2f654a794a554954676356;
03-25 08:42:52.363: D/WebViewActivity(30030): Issued by: CN=GeoTrust SSL CA,O=GeoTrust\, Inc.,C=US;
03-25 08:42:52.363: D/WebViewActivity(30030): on URL: https://test.company.com/some/page.aspx
03-25 08:42:52.733: D/WebViewActivity(30030): Auth { what=0 when=-1d1h30m25s561ms }
03-25 08:42:52.733: D/WebViewActivity(30030): !haveAuthenticated/{ what=0 when=-1d1h30m25s562ms }
03-25 08:42:52.823: D/WebViewActivity(30030): Auth { what=0 when=-1d1h30m25s655ms }
03-25 08:42:52.823: D/WebViewActivity(30030): haveAuthenticated/{ what=0 when=-1d1h30m25s656ms }