java 使用安全的 HTTPS 连接在 Android Webview 上设置凭据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4540972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set credentials on an Android Webview using secured HTTPS connection
提问by Mbolland
I would like to create an Android Webview that connects to a website via a secured HTTPS
connection with the use of credentials.
我想创建一个 Android Webview,它通过HTTPS
使用凭据的安全连接连接到网站。
First difficulty was to accept the certificate (private), it was solved with thisvery useful post.
第一个困难是接受证书(私人),这个非常有用的帖子解决了。
Second difficulty is to use credentials, I found thispost.
第二个困难是使用凭据,我发现了这篇文章。
(first answer from dparnas) which seems to deal pretty well with it, but it talks about HTTP
connection and not HTTPS
. I ve tried it, but it doesnt work, I just reach the sign-in form page without any error message, just the normal blank form.
(来自 dparnas 的第一个答案)似乎处理得很好,但它谈论的是HTTP
连接而不是HTTPS
. 我试过了,但它不起作用,我只是到达登录表单页面,没有任何错误消息,只是普通的空白表单。
Here is my code:
这是我的代码:
import android.app.Activity;
import android.net.http.SslError;
import android.os.Bundle;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class ConnectorWebView extends Activity {
WebView mWebView;
String mUsrName;
String mPassC;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.connwebview);
// Getting info from Intent extras
// Get it if it s different from null
Bundle extras = getIntent().getExtras();
mUsrName = extras != null ? extras.getString("username") : null;
mPassC = extras != null ? extras.getString("passcode") : null;
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setHttpAuthUsernamePassword("myhost.com", "myrealm", mUsrName, mPassC);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, String host, String realm){
handler.proceed(mUsrName, mPassC);
}
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
handler.proceed() ;
}
});
mWebView.loadUrl("https://myhost.com/secured_area");
}
}
回答by Marvin Pinto
As it seems that WebView
cannot natively handle Basic
authentication when using HTTPS
, I started toying with the idea of setting the Authorization
header (containing the encoded username/password) manually.
由于在使用 时似乎WebView
无法本地处理Basic
身份验证HTTPS
,因此我开始考虑Authorization
手动设置标头(包含编码的用户名/密码)的想法。
Here's how I think this can be done:
这是我认为可以做到的方法:
import org.apache.commons.codec.binary.Base64;
// ...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.connwebview);
// Getting info from Intent extras
// Get it if it s different from null
Bundle extras = getIntent().getExtras();
mUsrName = extras != null ? extras.getString("username") : null;
mPassC = extras != null ? extras.getString("passcode") : null;
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
// mWebView.setHttpAuthUsernamePassword("myhost.com",
// "myrealm",
// mUsrName,
// mPassC);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler,
String host,
String realm){
handler.proceed(mUsrName, mPassC);
}
public void onReceivedSslError(WebView view,
SslErrorHandler handler,
SslError error) {
handler.proceed() ;
}
});
String up = mUserName +":" +mPassC;
String authEncoded = new String(Base64.encodeBase64(up.getBytes()));
String authHeader = "Basic " +authEncoded;
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", authHeader);
mWebView.loadUrl("https://myhost.com/secured_area", headers);
}
This takes advantage of the WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)
method and for this example I'm using the Base64Encoder
from Apache Commons. The Base64Encoder part is quite trivial and if you didn't want to include external libraries in your application (for whatever reason), you could always write your own(reference).
这利用了该WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)
方法,对于本示例,我使用的是Base64Encoder
来自Apache Commons 的。Base64Encoder 部分非常简单,如果您不想在应用程序中包含外部库(无论出于何种原因),您始终可以编写自己的库(参考)。
Also note that the aforementioned WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)
method is only available in API 8+. For reference, see also the Wikipedia article on Basic Authentication(which discusses the headers, etc).
另请注意,上述WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)
方法仅适用于 API 8+。作为参考,另请参阅维基百科关于基本身份验证的文章(讨论标题等)。
回答by elijah
The WebView class doesn't provide as much flexibility in its connectivity as using the low level classes (such as HttpPost or the like) directly.
WebView 类在其连接性方面提供的灵活性不如直接使用低级类(例如 HttpPost 等)。
If you need to fully control the connection to the server -- or deal with complicated authorization scenarios such as this one -- use the low level classes, retrieve the data, then use WebView.loadData() to load and show the HTML.
如果您需要完全控制与服务器的连接——或者处理诸如此类的复杂授权场景——使用低级类,检索数据,然后使用 WebView.loadData() 加载和显示 HTML。
Hereis a good example of loading content using SSL and a BasicCredentialProvider. The result of this could be loaded into the WebView as described above.
这是使用 SSL 和 BasicCredentialProvider 加载内容的一个很好的示例。如上所述,可以将其结果加载到 WebView 中。
回答by Philzen
Alternative Scenario:
替代方案:
If willing to write roundabout 10 lines of javascript using jQuery, this scenario is rather simple.
如果愿意使用 jQuery编写迂回的 10 行 javascript,这个场景是相当简单的。
Inject your javascript code into the webviewor in case you're controlling the html page you are displaying, include it there.
将您的 javascript 代码注入到 webview 中,或者如果您正在控制正在显示的 html 页面,请将其包含在那里。
If you need to interface back from javascript, you can do that. For heavier command exchange, use the CordovaWebView
-Interface which has a lower delay depending on api level.
如果您需要从 javascript 返回接口,您可以这样做。对于更重的命令交换,请使用CordovaWebView
延迟较低的-Interface,具体取决于 api 级别。