且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用安全的HTTPS连接上Android的web视图设置凭证

更新时间:2023-08-27 14:13:22

,因为它似乎是的WebView 本身不能处理基本在使用 HTTPS 认证,我开始设置批准头(含的想法玩弄的EN codeD的用户名/密码),手动。

下面就是我觉得这是可以做到:

 进口org.apache.commons codec.binary.Base64。

// ...

@覆盖
公共无效的onCreate(包savedInstanceState){
  super.onCreate(savedInstanceState);
  的setContentView(R.layout.connwebview);

  //获取从意向额外信息
  //获取它,如果它■从空不同
  捆绑额外= getIntent()getExtras()。
  mUsrName =演员!= NULL? extras.getString(用户名):空;
  mPassC =演员!= NULL? extras.getString(通code):空;

  mWebView =(web视图)findViewById(R.id.webview);
  mWebView.getSettings()setJavaScriptEnabled(真)。
  // mWebView.setHttpAuthUsernamePassword(myhost.com
  //MYREALM
  // mUsrName,
  // mPassC);

  mWebView.setWebViewClient(新WebViewClient(){
      @覆盖
      公共无效onReceivedHttpAuthRequest(web视图来看,
                                            HttpAuthHandler处理程序,
                                            字符串主机,
                                            字符串的境界){
        handler.proceed(mUsrName,mPassC);
      }

      公共无效onReceivedSslError(web视图来看,
                                     SslErrorHandler处理程序,
                                     SslError错误){
        handler.proceed();
      }
    });

  串起来= mUserName +:+ mPassC;
  字符串:认证codeD =新的String(Base64.en codeBase64(up.getBytes()));
  字符串authHeader =基本+认证介绍codeD;
  地图<字符串,字符串>标题=新的HashMap<字符串,字符串>();
  headers.put(授权,authHeader);
  mWebView.loadUrl(https://myhost.com/secured_area,标题);
}
 

这充分利用了 WebView.loadUrl(字符串URL,地图<字符串,字符串> additionalHttpHeaders)的方法和这个例子中我使用了 Base64En codeR Apache的百科全书。该Base64En codeR一部分就十分简单了,如果你不想在应用程序中的外部库(无论何种原因),你总是可以写你的自己参考)。

另外还要注意的是,上述 WebView.loadUrl(字符串URL,地图<字符串,字符串> additionalHttpHeaders)方法仅适用于API提供8+。仅供参考,请参阅还对***的文章基本身份验证(其中讨论了头,等)。

I would like to create an Android Webview that connects to a website via a secured HTTPS connection with the use of credentials.

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. 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.

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).

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).