Я пытаюсь опубликовать запрос 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());
}
});
}