Android上的HTTPS身份验证

时间:2015-08-31 05:16:11

标签: java android https authorization

我有一些针对Android的HTTP身份验证代码。但它对https auth不起作用。如何在https授权下重新分配代码?

以下HTTP身份验证代码:

HttpUriRequest request = new HttpGet(HOST);
String credentials = login + ":" + mPassword;
authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("auth", authString);
editor.apply();
request.addHeader("Authorization", authString);
HttpClient httpClient = new DefaultHttpClient();

int result = 0;
try {
    HttpResponse response = httpClient.execute(request);
    result = response.getStatusLine().getStatusCode();
    System.out.println(response.getStatusLine());
} catch (Exception e) {
    result = -1;
}
return result;

2 个答案:

答案 0 :(得分:0)

  

然而,HttpClient的默认行为适合大多数用途   您可能想要配置一些方面。最多   自定义SSL的常见要求是:

     
      
  1. 能够接受自签名或不受信任的SSL证书。这是由SSLException突出显示的,其中包含消息Unrecognized SSL   在尝试连接时抛出握手(或类似的)。
  2.   
  3. 您希望使用第三方SSL库,而不是Sun的默认实现。
  4.   

您可能需要实现自定义协议:

Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", 
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
  httpclient.executeMethod(httpget);
  System.out.println(httpget.getStatusLine());
} finally {
  httpget.releaseConnection();
}

MySSLSocketFactory是一个实现org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory接口的自定义套接字工厂 您可以参考此链接:MySSLSocketFactory.java

答案 1 :(得分:0)

我解决了它,使用自定义ssl套接字工厂并使用params创建HTTP客户端。

CustomSSLSocketFactory:

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLSocketFactory;

public class CustomSSLSocketFactory extends SSLSocketFactory{
      SSLContext sslContext = SSLContext.getInstance("TLS");
      /**
       * Generate Certificate for ssl connection
       * @param truststore
       * @throws NoSuchAlgorithmException
       * @throws KeyManagementException
       * @throws KeyStoreException
       * @throws UnrecoverableKeyException
       */
      public CustomSSLSocketFactory(KeyStore truststore)
                  throws NoSuchAlgorithmException, KeyManagementException,
                  KeyStoreException, UnrecoverableKeyException {
            super(truststore);
            TrustManager tm = new X509TrustManager(){
                  @Override
                  public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                              throws CertificateException {
                  }
                  @Override
                  public void checkServerTrusted(X509Certificate[] chain,
                              String authType) throws CertificateException {
                  }
                  @Override
                  public X509Certificate[] getAcceptedIssuers() {
                        return null;
                  }
            };
            sslContext.init(null, new TrustManager[] {tm}, null);
      }

      @Override
      public Socket createSocket(Socket socket, String host, int port,
                  boolean autoClose) throws IOException, UnknownHostException {
            return sslContext.getSocketFactory().createSocket(socket, host, port,
                        autoClose);
      }

      @Override
      public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
      }
}

用于创建HTTP客户端的End util:

import java.security.KeyStore;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

public class HTTPUtils {
      /**
       * HttpClient
       * @param isHTTPS
       * @return
       */
      public static HttpClient getNewHttpClient(boolean isHTTPS) {
            try {
                  if(!isHTTPS){
                        return getNewHttpClient();
                  }
                  KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                  trustStore.load(null, null);
                  SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
                  sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

                  HttpParams params = new BasicHttpParams();
                  SchemeRegistry registry = new SchemeRegistry();
                  registry.register(new Scheme("https", sf, 443));

                  ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
                  return new DefaultHttpClient(ccm, params);
            } catch (Exception e) {
                  return null;
            }
      }
      /**
       * HttpClient for http request
       * @return
       */
      private static HttpClient getNewHttpClient(){
            HttpParams params = new BasicHttpParams();
            return new DefaultHttpClient(params);
      }
}

示例:

String credentials = login + ":" + mPassword;
            authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
            HttpClient httpclient = HTTPUtils.getNewHttpClient(HOST.startsWith(HTTPS_STRING));
            URI newURI = URI.create(HOST);
            HttpGet httpGet =  new HttpGet(newURI);
            httpGet.setHeader("Authorization", authString);

            try {
                HttpResponse response = httpclient.execute(httpGet);
                int code = response.getStatusLine().getStatusCode();
                return code;
...
相关问题