我试图在webview中加载带有基本身份验证的SSL页面,但即使我在onReceivedSslError中运行proceed()并且usr / pwd是正确的,我也无法通过onReceivedHttpAuthRequest。如果我删除下面代码中的hasAuthenticated检查,它只是无休止地循环使用身份验证请求,就像凭据错误一样。似乎在尝试验证时它不会接受证书。
添加基本的auth标头并没有改变任何东西,还有其他方法可以解决这个问题吗?
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);
}
}
奇怪的是,它可以在某些设备上运行,但不是全部,例如华硕Padfone 2没有以下日志。
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 }