В запросе https с клиентским сертификатом отказано в доступе в android, но это хорошо работает в post man, дооснащение и okhttp3 возвращают ту же ошибку - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь опубликовать запрос https с помощью okhttp3 или retrofit2 с локально добавленным клиентским сертификатом ssl в android raw dir в виде файла .pfx, но веб-API возвращается с отказом в доступе и кодом ответа 403, но тот же сценарий работает хорошо в почтальоне

public class OkhttpManager {
static private OkhttpManager mOkhttpManager=null;
private InputStream mTrustrCertificate;
OkHttpClient okHttpClient;

static public OkhttpManager getInstance()
{
    if(mOkhttpManager==null)
    {
        mOkhttpManager=new OkhttpManager();
    }
    return mOkhttpManager;
 }

 private X509TrustManager trustManagerForCertificates(InputStream in)
        throws GeneralSecurityException {

    // Use it to build an X509 trust manager.
    char[] password = "123456".toCharArray();
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    try {
        keyStore.load(getTrustrCertificates(),password);
    } catch (IOException e) {
        e.printStackTrace();
    }
    KeyManagerFactory keyManagerFactory  =KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, password);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
    if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
        throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
    }
    return (X509TrustManager) trustManagers[0];
}

public void setTrustrCertificates(InputStream ic)
{
    mTrustrCertificate = ic;
}

public InputStream getTrustrCertificates()
{
    return mTrustrCertificate;
}

public OkHttpClient build()
{
    List<Protocol> protocols = new ArrayList<>();
    protocols.add(Protocol.HTTP_1_1);

    if(getTrustrCertificates()!=null)
    {
        X509TrustManager trustManager;
        SSLSocketFactory sslSocketFactory;
        try {
            trustManager = trustManagerForCertificates(getTrustrCertificates());
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[] { trustManager }, null);
            sslSocketFactory = sslContext.getSocketFactory();
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }

        List<ConnectionSpec> connectionSpecs = new LinkedList<>();
        ConnectionSpec strict = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                .tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
                .build();
        connectionSpecs.add(strict);

     okHttpClient=new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory, trustManager)
                .addInterceptor(new SslCertificateLogger())
                .protocols(protocols)
                .connectionSpecs(connectionSpecs)
                .readTimeout(45, TimeUnit.SECONDS)
                .writeTimeout(45,TimeUnit.SECONDS)
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String s, SSLSession sslSession) {
                        if (s.equals("my host name")){
                            return true;
                        }else
                            return false;
                    }
                })
                .build();


    }
    else
    {

        okHttpClient=new OkHttpClient.Builder()
                .readTimeout(45, TimeUnit.SECONDS)
                .writeTimeout(45,TimeUnit.SECONDS)
                .protocols(protocols)
                .build();

    }
    return okHttpClient;
}}

/ ////////

вот как вызвать okhttpmanager и сделать запрос okhttp3

 void postRequest(String postUrl,String postBody) throws IOException {

    OkhttpManager client = new OkhttpManager();

    try {
        InputStream caInput = getResources().openRawResource(R.raw.filename);
        OkhttpManager.getInstance().setTrustrCertificates(caInput);
    } catch (Exception e) {
        e.printStackTrace();
    }

    RequestBody body = RequestBody.create(JSON, postBody);

    Request request = new Request.Builder()
            .url(postUrl)
            .post(body)
            .build();

    request.header("Content-type : application/json; charset=utf-8");


    client.build().newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            call.cancel();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d("TAG", response.body().string());
        }
    });
}

1 Ответ

0 голосов
/ 05 марта 2020
 <application
        android:usesCleartextTraffic="true">

    </application>

включить его в манифесте

...