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

发布于 2024-10-09 12:05:53 字数 1959 浏览 7 评论 0原文

我想创建一个 Android Webview,它使用凭据通过安全的 HTTPS 连接连接到网站。

第一个困难是接受证书(私有),它通过 这篇非常有用的帖子。

第二个困难是使用凭据,我找到了这篇帖子。

(dparnas 的第一个答案)似乎处理得很好,但它讨论的是 HTTP 连接而不是 HTTPS。我已经尝试过,但它不起作用,我只是到达登录表单页面,没有任何错误消息,只有正常的空白表单。

这是我的代码:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以可爱出名 2024-10-16 12:05:53

由于使用 HTTPS 时,WebView 似乎无法本机处理 Basic 身份验证,因此我开始考虑设置 Authorization 的想法code> 标头(包含编码的用户名/密码)手动。

我认为可以这样做:

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

这利用了 WebView.loadUrl (String url, MapadditionalHttpHeaders) 方法,在本示例中,我使用 Base64Encoder 来自 Apache Commons。 Base64Encoder 部分非常简单,如果您不想在应用程序中包含外部库(无论出于何种原因),您始终可以编写 自己的参考)。

另请注意,上述 WebView.loadUrl (String url, MapadditionalHttpHeaders) 方法仅在 API 8+ 中可用。作为参考,另请参阅有关基本身份验证的维基百科文章(其中讨论了标头等)。

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

以酷 2024-10-16 12:05:53

WebView 类在连接方面没有提供与直接使用低级类(例如 HttpPost 等)一样多的灵活性。

如果您需要完全控制与服务器的连接,或者处理像这样的复杂授权场景,请使用低级类,检索数据,然后使用 WebView.loadData() 加载并显示 HTML。

这里是使用 SSL 加载内容的一个很好的示例一个BasicCredentialProvider。如上所述,结果可以加载到 WebView 中。

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.

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.

Here is a good example of loading content using SSL and a BasicCredentialProvider. The result of this could be loaded into the WebView as described above.

卸妝后依然美 2024-10-16 12:05:53

替代方案

如果愿意写使用 jQuery 绕了 10 行 javascript,这个场景相当简单。

将您的 javascript 代码注入到 webview 或者如果您控制您正在显示的 html 页面,将其包含在那里。

如果您需要从 javascript 返回接口,您可以这样做。对于更繁重的命令交换,请使用 CordovaWebView - 根据 api 级别具有较低延迟的接口。

Alternative Scenario:

If willing to write roundabout 10 lines of javascript using jQuery, this scenario is rather simple.

Inject your javascript code into the webview or in case you're controlling the html page you are displaying, include it there.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文