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