Skip to content

Commit 9d82377

Browse files
committed
Pass through connection builder to token requests
1 parent 255fad4 commit 9d82377

File tree

2 files changed

+155
-24
lines changed

2 files changed

+155
-24
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.reactlibrary;
2+
3+
/*
4+
* Copyright 2016 The AppAuth for Android Authors. All Rights Reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7+
* in compliance with the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software distributed under the
12+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+
* express or implied. See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
18+
import android.annotation.SuppressLint;
19+
import android.net.Uri;
20+
import android.support.annotation.NonNull;
21+
import android.support.annotation.Nullable;
22+
import android.util.Log;
23+
24+
import net.openid.appauth.Preconditions;
25+
import net.openid.appauth.connectivity.ConnectionBuilder;
26+
27+
import java.io.IOException;
28+
import java.net.HttpURLConnection;
29+
import java.net.URL;
30+
import java.security.KeyManagementException;
31+
import java.security.NoSuchAlgorithmException;
32+
import java.security.cert.X509Certificate;
33+
import java.util.concurrent.TimeUnit;
34+
35+
import javax.net.ssl.HostnameVerifier;
36+
import javax.net.ssl.HttpsURLConnection;
37+
import javax.net.ssl.SSLContext;
38+
import javax.net.ssl.SSLSession;
39+
import javax.net.ssl.TrustManager;
40+
import javax.net.ssl.X509TrustManager;
41+
42+
/**
43+
* An implementation of {@link ConnectionBuilder} that permits connecting to http
44+
* links, and ignores certificates for https connections. *THIS SHOULD NOT BE USED IN PRODUCTION
45+
* CODE*. It is intended to facilitate easier testing of AppAuth against development servers
46+
* only.
47+
*/
48+
public final class ConnectionBuilderForTesting implements ConnectionBuilder {
49+
50+
public static final ConnectionBuilderForTesting INSTANCE = new ConnectionBuilderForTesting();
51+
52+
private static final String TAG = "ConnBuilder";
53+
54+
private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(15);
55+
private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(10);
56+
57+
private static final String HTTP = "http";
58+
private static final String HTTPS = "https";
59+
60+
@SuppressLint("TrustAllX509TrustManager")
61+
private static final TrustManager[] ANY_CERT_MANAGER = new TrustManager[] {
62+
new X509TrustManager() {
63+
public X509Certificate[] getAcceptedIssuers() {
64+
return null;
65+
}
66+
67+
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
68+
69+
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
70+
}
71+
};
72+
73+
@SuppressLint("BadHostnameVerifier")
74+
private static final HostnameVerifier ANY_HOSTNAME_VERIFIER = new HostnameVerifier() {
75+
public boolean verify(String hostname, SSLSession session) {
76+
return true;
77+
}
78+
};
79+
80+
@Nullable
81+
private static final SSLContext TRUSTING_CONTEXT;
82+
83+
static {
84+
SSLContext context;
85+
try {
86+
context = SSLContext.getInstance("SSL");
87+
} catch (NoSuchAlgorithmException e) {
88+
Log.e("ConnBuilder", "Unable to acquire SSL context");
89+
context = null;
90+
}
91+
92+
SSLContext initializedContext = null;
93+
if (context != null) {
94+
try {
95+
context.init(null, ANY_CERT_MANAGER, new java.security.SecureRandom());
96+
initializedContext = context;
97+
} catch (KeyManagementException e) {
98+
Log.e(TAG, "Failed to initialize trusting SSL context");
99+
}
100+
}
101+
102+
TRUSTING_CONTEXT = initializedContext;
103+
}
104+
105+
private ConnectionBuilderForTesting() {
106+
// no need to construct new instances
107+
}
108+
109+
@NonNull
110+
@Override
111+
public HttpURLConnection openConnection(@NonNull Uri uri) throws IOException {
112+
Preconditions.checkNotNull(uri, "url must not be null");
113+
Preconditions.checkArgument(HTTP.equals(uri.getScheme()) || HTTPS.equals(uri.getScheme()),
114+
"scheme or uri must be http or https");
115+
HttpURLConnection conn = (HttpURLConnection) new URL(uri.toString()).openConnection();
116+
conn.setConnectTimeout(CONNECTION_TIMEOUT_MS);
117+
conn.setReadTimeout(READ_TIMEOUT_MS);
118+
conn.setInstanceFollowRedirects(false);
119+
120+
if (conn instanceof HttpsURLConnection && TRUSTING_CONTEXT != null) {
121+
HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
122+
httpsConn.setSSLSocketFactory(TRUSTING_CONTEXT.getSocketFactory());
123+
httpsConn.setHostnameVerifier(ANY_HOSTNAME_VERIFIER);
124+
}
125+
126+
return conn;
127+
}
128+
}

android/src/main/java/com/reactlibrary/RNAppAuthModule.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.facebook.react.bridge.ReadableMapKeySetIterator;
1919
import com.facebook.react.bridge.WritableMap;
2020

21+
import net.openid.appauth.AppAuthConfiguration;
2122
import net.openid.appauth.AuthorizationException;
2223
import net.openid.appauth.AuthorizationRequest;
2324
import net.openid.appauth.AuthorizationResponse;
@@ -45,6 +46,7 @@ public class RNAppAuthModule extends ReactContextBaseJavaModule implements Activ
4546

4647
private final ReactApplicationContext reactContext;
4748
private Promise promise;
49+
private Boolean dangerouslyAllowInsecureHttpRequests;
4850

4951
public RNAppAuthModule(ReactApplicationContext reactContext) {
5052
super(reactContext);
@@ -109,7 +111,7 @@ private HashMap<String, String> additionalParametersToMap(ReadableMap additional
109111
private ConnectionBuilder createConnectionBuilder(Boolean allowInsecureConnections) {
110112

111113
if (allowInsecureConnections.equals(true)) {
112-
return new UnsafeConnectionBuilder();
114+
return ConnectionBuilderForTesting.INSTANCE;
113115
}
114116

115117
return DefaultConnectionBuilder.INSTANCE;
@@ -135,6 +137,7 @@ public void authorize(
135137

136138
final Context context = this.reactContext;
137139
this.promise = promise;
140+
this.dangerouslyAllowInsecureHttpRequests = dangerouslyAllowInsecureHttpRequests;
138141
final Activity currentActivity = getCurrentActivity();
139142

140143
final String scopesString = this.arrayToString(scopes);
@@ -152,6 +155,7 @@ public void onFetchConfigurationCompleted(
152155
return;
153156
}
154157

158+
155159
AuthorizationRequest.Builder authRequestBuilder =
156160
new AuthorizationRequest.Builder(
157161
serviceConfiguration,
@@ -165,9 +169,14 @@ public void onFetchConfigurationCompleted(
165169
authRequestBuilder.setAdditionalParameters(additionalParametersToMap(additionalParameters));
166170
}
167171

168-
AuthorizationRequest authRequest = authRequestBuilder.build();
172+
AppAuthConfiguration configuration =
173+
new AppAuthConfiguration
174+
.Builder()
175+
.setConnectionBuilder(builder)
176+
.build();
169177

170-
AuthorizationService authService = new AuthorizationService(context);
178+
AuthorizationRequest authRequest = authRequestBuilder.build();
179+
AuthorizationService authService = new AuthorizationService(context, configuration);
171180
Intent authIntent = authService.getAuthorizationRequestIntent(authRequest);
172181
currentActivity.startActivityForResult(authIntent, 0);
173182

@@ -194,6 +203,8 @@ public void refresh(
194203
final Uri issuerUri = Uri.parse(issuer);
195204
final ConnectionBuilder builder = createConnectionBuilder(dangerouslyAllowInsecureHttpRequests);
196205

206+
this.dangerouslyAllowInsecureHttpRequests = dangerouslyAllowInsecureHttpRequests;
207+
197208
AuthorizationServiceConfiguration.fetchFromUrl(
198209
buildConfigurationUriFromIssuer(issuerUri),
199210
new AuthorizationServiceConfiguration.RetrieveConfigurationCallback() {
@@ -221,7 +232,12 @@ public void onFetchConfigurationCompleted(
221232
TokenRequest tokenRequest = tokenRequestBuilder.build();
222233

223234

224-
AuthorizationService authService = new AuthorizationService(context);
235+
final AppAuthConfiguration configuration =
236+
new AppAuthConfiguration
237+
.Builder()
238+
.setConnectionBuilder(createConnectionBuilder(dangerouslyAllowInsecureHttpRequests))
239+
.build();
240+
AuthorizationService authService = new AuthorizationService(context, configuration);
225241

226242
authService.performTokenRequest(tokenRequest, new AuthorizationService.TokenResponseCallback() {
227243
@Override
@@ -252,7 +268,13 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode,
252268

253269
final Promise authorizePromise = this.promise;
254270

255-
AuthorizationService authService = new AuthorizationService(this.reactContext);
271+
final AppAuthConfiguration configuration =
272+
new AppAuthConfiguration
273+
.Builder()
274+
.setConnectionBuilder(createConnectionBuilder(this.dangerouslyAllowInsecureHttpRequests))
275+
.build();
276+
277+
AuthorizationService authService = new AuthorizationService(this.reactContext, configuration);
256278

257279
authService.performTokenRequest(
258280
response.createTokenExchangeRequest(),
@@ -282,23 +304,4 @@ public void onNewIntent(Intent intent) {
282304
public String getName() {
283305
return "RNAppAuth";
284306
}
285-
}
286-
287-
288-
final class UnsafeConnectionBuilder implements ConnectionBuilder {
289-
290-
private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(15);
291-
private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(10);
292-
293-
294-
@NonNull
295-
@Override
296-
public HttpURLConnection openConnection(@NonNull Uri uri) throws IOException {
297-
Preconditions.checkNotNull(uri, "url must not be null");
298-
HttpURLConnection conn = (HttpURLConnection) new URL(uri.toString()).openConnection();
299-
conn.setConnectTimeout(CONNECTION_TIMEOUT_MS);
300-
conn.setReadTimeout(READ_TIMEOUT_MS);
301-
conn.setInstanceFollowRedirects(false);
302-
return conn;
303-
}
304307
}

0 commit comments

Comments
 (0)