-
-
Save demixdn/3886de5a71dc2812c8f4d27a248a506b to your computer and use it in GitHub Desktop.
| package <you_package>.data.api; | |
| import android.content.Context; | |
| import android.support.annotation.NonNull; | |
| import com.google.gson.ExclusionStrategy; | |
| import com.google.gson.FieldAttributes; | |
| import com.google.gson.Gson; | |
| import com.google.gson.GsonBuilder; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.security.KeyManagementException; | |
| import java.security.KeyStore; | |
| import java.security.KeyStoreException; | |
| import java.security.NoSuchAlgorithmException; | |
| import java.security.cert.Certificate; | |
| import java.security.cert.CertificateException; | |
| import java.security.cert.CertificateFactory; | |
| import java.util.concurrent.TimeUnit; | |
| import javax.net.ssl.SSLContext; | |
| import javax.net.ssl.TrustManagerFactory; | |
| import io.realm.RealmObject; | |
| import okhttp3.OkHttpClient; | |
| import okhttp3.Request; | |
| import okhttp3.logging.HttpLoggingInterceptor; | |
| import retrofit2.GsonConverterFactory; | |
| import retrofit2.Retrofit; | |
| import retrofit2.RxJavaCallAdapterFactory; | |
| import <you_package>.BuildConfig; | |
| import <you_package>.utils.LogUtils; | |
| public class ApiModule { | |
| @NonNull | |
| private final String baseUrl; | |
| @NonNull | |
| private static Gson gson; | |
| @NonNull | |
| private final OkHttpClient.Builder httpClientBuilder; | |
| /** | |
| * Create Rertofit params: logging, ssl connection and access token | |
| * @param baseUrl endpoint of service | |
| * @param authToken access token for connection, must be NULL in auth request | |
| */ | |
| public ApiModule(@NonNull String baseUrl, @NonNull Context context, String authToken){ | |
| this.baseUrl = baseUrl; | |
| httpClientBuilder = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS); | |
| initGson(); | |
| initHttpLogging(HttpLoggingInterceptor.Level.BODY); | |
| initSSL(context); | |
| initAuthToken(authToken); | |
| } | |
| private void initGson() { | |
| GsonBuilder gsonBuilder = new GsonBuilder(); | |
| gsonBuilder.setExclusionStrategies(new ExclusionStrategy() { | |
| @Override | |
| public boolean shouldSkipField(FieldAttributes f) { | |
| return f.getDeclaringClass().equals(RealmObject.class); | |
| } | |
| @Override | |
| public boolean shouldSkipClass(Class<?> clazz) { | |
| return false; | |
| } | |
| }); | |
| gson = gsonBuilder.create(); | |
| } | |
| private void initHttpLogging(HttpLoggingInterceptor.Level level) { | |
| HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); | |
| logging.setLevel(level); | |
| if(BuildConfig.DEBUG) | |
| httpClientBuilder.addInterceptor(logging); | |
| } | |
| /** | |
| * ToDo modify this: set param is InputStream from certificate file,move beyond the context of the module | |
| * @param context for read InputSream from raw resources | |
| */ | |
| private void initSSL(@NonNull Context context) { | |
| SSLContext sslContext = null; | |
| try { | |
| sslContext = createCertificate(context.getResources().openRawResource(R.raw.certificate)); | |
| } catch (CertificateException | IOException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) { | |
| e.printStackTrace(); | |
| } | |
| if(sslContext!=null) | |
| httpClientBuilder.sslSocketFactory(sslContext.getSocketFactory()); | |
| } | |
| public void initAuthToken(String authToken) { | |
| LogUtils.E("initAuthToken - "+authToken); | |
| if (authToken != null) { | |
| httpClientBuilder.addInterceptor(chain -> { | |
| Request original = chain.request(); | |
| Request.Builder requestBuilder = original.newBuilder() | |
| .header("Authorization", authToken) | |
| .method(original.method(), original.body()); | |
| Request request = requestBuilder.build(); | |
| return chain.proceed(request); | |
| }); | |
| } | |
| } | |
| private SSLContext createCertificate(InputStream trustedCertificateIS) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { | |
| CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
| Certificate ca; | |
| try { | |
| ca = cf.generateCertificate(trustedCertificateIS); | |
| } finally { | |
| trustedCertificateIS.close(); | |
| } | |
| // creating a KeyStore containing our trusted CAs | |
| String keyStoreType = KeyStore.getDefaultType(); | |
| KeyStore keyStore = KeyStore.getInstance(keyStoreType); | |
| keyStore.load(null, null); | |
| keyStore.setCertificateEntry("ca", ca); | |
| // creating a TrustManager that trusts the CAs in our KeyStore | |
| String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); | |
| TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); | |
| tmf.init(keyStore); | |
| // creating an SSLSocketFactory that uses our TrustManager | |
| SSLContext sslContext = SSLContext.getInstance("TLS"); | |
| sslContext.init(null, tmf.getTrustManagers(), null); | |
| return sslContext; | |
| } | |
| @NonNull | |
| public RestAPI provideApiRx() | |
| { | |
| return new Retrofit.Builder() | |
| .baseUrl(baseUrl) | |
| .addConverterFactory(GsonConverterFactory.create(gson)) | |
| .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) | |
| .client(httpClientBuilder.build()) | |
| .build() | |
| .create(RestAPI.class); | |
| } | |
| @NonNull | |
| public RestAPI provideApi() | |
| { | |
| return new Retrofit.Builder() | |
| .baseUrl(baseUrl) | |
| .addConverterFactory(GsonConverterFactory.create(gson)) | |
| .client(httpClientBuilder.build()) | |
| .build() | |
| .create(RestAPI.class); | |
| } | |
| } |
What's the format/how should the raw certificate look like?
What's the format/how should the raw certificate look like?
The raw certificate contents might look like this.
-----BEGIN CERTIFICATE----- MIIGJzCCBA+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBsjELMAkGA1UEBhMCRlIx DzANBgNVBAgMBkFsc2FjZTETMBEGA1UEBwwKU3RyYXNib3VyZzEYMBYGA1UECgwP d3d3LmZyZWVsYW4ub3JnMRAwDgYDVQQLDAdmcmVlbGFuMS0wKwYDVQQDDCRGcmVl bGFuIFNhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxIjAgBgkqhkiG9w0BCQEW E2NvbnRhY3RAZnJlZWxhbi5vcmcwHhcNMTIwNDI3MTAzMTE4WhcNMjIwNDI1MTAz MTE4WjB+MQswCQYDVQQGEwJGUjEPMA0GA1UECAwGQWxzYWNlMRgwFgYDVQQKDA93 d3cuZnJlZWxhbi5vcmcxEDAOBgNVBAsMB2ZyZWVsYW4xDjAMBgNVBAMMBWFsaWNl MSIwIAYJKoZIhvcNAQkBFhNjb250YWN0QGZyZWVsYW4ub3JnMIICIjANBgkqhkiG 9w0BAQEFAAOCAg8AMIICCgKCAgEA3W29+ID6194bH6ejLrIC4hb2Ugo8v6ZC+Mrc k2dNYMNPjcOKABvxxEtBamnSaeU/IY7FC/giN622LEtV/3oDcrua0+yWuVafyxmZ yTKUb4/GUgafRQPf/eiX9urWurtIK7XgNGFNUjYPq4dSJQPPhwCHE/LKAykWnZBX RrX0Dq4XyApNku0IpjIjEXH+8ixE12wH8wt7DEvdO7T3N3CfUbaITl1qBX+Nm2Z6 q4Ag/u5rl8NJfXg71ZmXA3XOj7zFvpyapRIZcPmkvZYn7SMCp8dXyXHPdpSiIWL2 uB3KiO4JrUYvt2GzLBUThp+lNSZaZ/Q3yOaAAUkOx+1h08285Pi+P8lO+H2Xic4S vMq1xtLg2bNoPC5KnbRfuFPuUD2/3dSiiragJ6uYDLOyWJDivKGt/72OVTEPAL9o 6T2pGZrwbQuiFGrGTMZOvWMSpQtNl+tCCXlT4mWqJDRwuMGrI4DnnGzt3IKqNwS4 Qyo9KqjMIPwnXZAmWPm3FOKe4sFwc5fpawKO01JZewDsYTDxVj+cwXwFxbE2yBiF z2FAHwfopwaH35p3C6lkcgP2k/zgAlnBluzACUI+MKJ/G0gv/uAhj1OHJQ3L6kn1 SpvQ41/ueBjlunExqQSYD7GtZ1Kg8uOcq2r+WISE3Qc9MpQFFkUVllmgWGwYDuN3 Zsez95kCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFFlfyRO6G8y5qEFKikl5 ajb2fT7XMB8GA1UdIwQYMBaAFCNsLT0+KV14uGw+quK7Lh5sh/JTMA0GCSqGSIb3 DQEBBQUAA4ICAQAT5wJFPqervbja5+90iKxi1d0QVtVGB+z6aoAMuWK+qgi0vgvr mu9ot2lvTSCSnRhjeiP0SIdqFMORmBtOCFk/kYDp9M/91b+vS+S9eAlxrNCB5VOf PqxEPp/wv1rBcE4GBO/c6HcFon3F+oBYCsUQbZDKSSZxhDm3mj7pb67FNbZbJIzJ 70HDsRe2O04oiTx+h6g6pW3cOQMgIAvFgKN5Ex727K4230B0NIdGkzuj4KSML0NM slSAcXZ41OoSKNjy44BVEZv0ZdxTDrRM4EwJtNyggFzmtTuV02nkUj1bYYYC5f0L ADr6s0XMyaNk8twlWYlYDZ5uKDpVRVBfiGcq0uJIzIvemhuTrofh8pBQQNkPRDFT Rq1iTo1Ihhl3/Fl1kXk1WR3jTjNb4jHX7lIoXwpwp767HAPKGhjQ9cFbnHMEtkro RlJYdtRq5mccDtwT0GFyoJLLBZdHHMHJz0F9H7FNk2tTQQMhK5MVYwg+LIaee586 CQVqfbscp7evlgjLW98H+5zylRHAgoH2G79aHljNKMp9BOuq6SnEglEsiWGVtu2l hnx8SB3sVJZHeer8f/UQQwqbAO+Kdy70NmbSaqaVtp8jOxLiidWkwSyRTsuU6D8i DiH5uEqBXExjrj0FslxcVKdVj5glVcSmkLwZKbEU1OKwleT/iXFhvooWhQ== -----END CERTIFICATE-----
Note this is a sample.
Don't use it on production!
Thanks alot.