简体   繁体   English

使用安全的HTTPS连接在Android Webview上设置凭据

[英]Set credentials on an Android Webview using secured HTTPS connection

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 this very useful post. 第一个困难是接受证书(私人), 这一非常有用的帖子解决了这个问题。

Second difficulty is to use credentials, I found this post. 第二个困难是使用凭据,我发现了这篇文章。

(first answer from dparnas) which seems to deal pretty well with it, but it talks about HTTP connection and not HTTPS . (来自dparnas的第一个答案)似乎处理得很好,但是它讨论的是HTTP连接,而不是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. 我已经尝试过了,但是没有用,我只是进入登录表单页面而没有任何错误消息,只是正常的空白表单。

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

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在使用HTTPS时无法本地处理Basic身份验证,我开始尝试手动设置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 . 这利用了WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)方法的优势,在本示例中,我使用Apache CommonsBase64Encoder 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 ). Base64Encoder部分非常琐碎,如果您不希望在应用程序中包括外部库(无论出于何种原因),则始终可以编写自己的参考 )。

Also note that the aforementioned WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders) method is only available in API 8+. 另请注意,上述WebView.loadUrl (String url, Map<String, String> additionalHttpHeaders)方法仅在API 8+中可用。 For reference, see also the Wikipedia article on Basic Authentication (which discusses the headers, etc). 作为参考,另请参阅有关基本身份验证的Wikipedia文章(讨论标题等)。

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。

Here is a good example of loading content using SSL and a BasicCredentialProvider. 是一个使用SSL和BasicCredentialProvider加载内容的好例子。 The result of this could be loaded into the WebView as described above. 如上所述,其结果可以加载到WebView中。

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 webview or 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. 如果您需要从javascript返回界面 ,则可以这样做。 For heavier command exchange, use the CordovaWebView -Interface which has a lower delay depending on api level. 为了进行更重的命令交换,请使用CordovaWebView -Interface,它的延迟取决于API级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM