gpt4 book ai didi

android - 使用 webview 和代理进行身份验证

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:55:31 25 4
gpt4 key购买 nike

我需要在 WebView 中加载一些在一个国家/地区不可用的 url,因此我尝试使用 WebView 的代理。我在 SO ( https://stackoverflow.com/a/18453384/7478869 ) 上找到了一个解决方案,它可以在没有身份验证的情况下使用代理。但我需要使用用户和密码设置代理。

有些方法没有帮助:

1) 加载带有标题的 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 ;
}
}

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);
}

2)在setProxy方法中添加密码和用户(完整代码如下):

        Authenticator.setDefault(
new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
user, password.toCharArray());
}
}
);

System.setProperty("http.proxyUser", user);
System.setProperty("http.proxyPassword", password);
System.setProperty("https.proxyUser", user);
System.setProperty("https.proxyPassword", password );

但是还是报错

[WARNING:http_network_transaction.cc(339)] Blocked proxy response with status 407 to CONNECT request for example.com:443

在 WebView 中:ERR_TUNNEL_CONNECTION_FAILED

完整代码:

public class MainActivity extends AppCompatActivity {
public static final String LOG_TAG = "Main";
WebView webview;
String applicationClassName="android.app.Application";
String user = "web";
String password = "password";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webview = findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);

String databasePath = webview.getContext().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
webview.getSettings().setDatabaseEnabled(true);
webview.getSettings().setDatabasePath(databasePath);
webview.getSettings().setAppCacheMaxSize(5 * 1048576);
webview.getSettings().setAppCachePath(databasePath);
webview.getSettings().setAppCacheEnabled(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setDomStorageEnabled(true);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);

setProxy(webview, "85.10.195.100", 443, applicationClassName, user, password);
webview.setWebViewClient(new ProxyAuthWebViewClient(user,password));
loadUrl(webview,"https://example.com",user,password);

}

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 ;
}
}

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);
}


public static boolean setProxy(WebView webview, String host, int port, String applicationClassName, String user,
String password) {
return setProxyKKPlus(webview, host, port, user, password, applicationClassName);
}


// from https://stackoverflow.com/questions/19979578/android-webview-set-proxy-programatically-kitkat
@SuppressLint("NewApi")
@SuppressWarnings("all")
private static boolean setProxyKKPlus(WebView webView, String host, int port, final String user,
final String password, String applicationClassName) {
Log.d(LOG_TAG, "Setting proxy with >= 4.4 API.");

Context appContext = webView.getContext().getApplicationContext();
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", port + "");
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", port + "");


Authenticator.setDefault(
new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
user, password.toCharArray());
}
}
);

System.setProperty("http.proxyUser", user);
System.setProperty("http.proxyPassword", password);
System.setProperty("https.proxyUser", user);
System.setProperty("https.proxyPassword", password );

try {
Class applictionCls = Class.forName(applicationClassName);
Field loadedApkField = applictionCls.getField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);

onReceiveMethod.invoke(rec, appContext, intent);
}
}
}

Log.d(LOG_TAG, "Setting proxy with >= 4.4 API successful!");
return true;
} catch (ClassNotFoundException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (NoSuchFieldException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (IllegalAccessException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (IllegalArgumentException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (NoSuchMethodException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (InvocationTargetException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
}
return false;
}
}

如何在WebView中正确使用带认证的代理?

最佳答案

好的,所以我找到了答案。需要在WebViewClient

中添加 onReceivedHttpAuthRequest
 @Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
handler.proceed(user,password);
}

关于android - 使用 webview 和代理进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54957724/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com