24
24
25
25
import com .rnappauth .utils .MapUtil ;
26
26
import com .rnappauth .utils .UnsafeConnectionBuilder ;
27
+ import com .rnappauth .utils .RegistrationResponseFactory ;
27
28
import com .rnappauth .utils .TokenResponseFactory ;
28
29
import com .rnappauth .utils .CustomConnectionBuilder ;
29
30
36
37
import net .openid .appauth .ClientAuthentication ;
37
38
import net .openid .appauth .ClientSecretBasic ;
38
39
import net .openid .appauth .ClientSecretPost ;
40
+ import net .openid .appauth .RegistrationRequest ;
41
+ import net .openid .appauth .RegistrationResponse ;
39
42
import net .openid .appauth .ResponseTypeValues ;
40
43
import net .openid .appauth .TokenResponse ;
41
44
import net .openid .appauth .TokenRequest ;
42
45
import net .openid .appauth .connectivity .ConnectionBuilder ;
43
46
import net .openid .appauth .connectivity .DefaultConnectionBuilder ;
44
47
48
+ import java .util .ArrayList ;
45
49
import java .util .Collections ;
46
50
import java .util .HashMap ;
51
+ import java .util .List ;
47
52
import java .util .Map ;
48
53
import java .util .concurrent .atomic .AtomicReference ;
49
54
import java .util .concurrent .CountDownLatch ;
@@ -56,6 +61,7 @@ public class RNAppAuthModule extends ReactContextBaseJavaModule implements Activ
56
61
private Promise promise ;
57
62
private Boolean dangerouslyAllowInsecureHttpRequests ;
58
63
private String clientAuthMethod = "basic" ;
64
+ private Map <String , String > registrationRequestHeaders = null ;
59
65
private Map <String , String > authorizationRequestHeaders = null ;
60
66
private Map <String , String > tokenRequestHeaders = null ;
61
67
private Map <String , String > additionalParametersMap ;
@@ -130,6 +136,75 @@ public void onFetchConfigurationCompleted(
130
136
}
131
137
}
132
138
139
+ @ ReactMethod
140
+ public void register (
141
+ String issuer ,
142
+ final ReadableArray redirectUris ,
143
+ final ReadableArray responseTypes ,
144
+ final ReadableArray grantTypes ,
145
+ final String subjectType ,
146
+ final String tokenEndpointAuthMethod ,
147
+ final ReadableMap additionalParameters ,
148
+ final ReadableMap serviceConfiguration ,
149
+ final Boolean dangerouslyAllowInsecureHttpRequests ,
150
+ final ReadableMap headers ,
151
+ final Promise promise
152
+ ) {
153
+ this .parseHeaderMap (headers );
154
+ final ConnectionBuilder builder = createConnectionBuilder (dangerouslyAllowInsecureHttpRequests , this .registrationRequestHeaders );
155
+ final AppAuthConfiguration appAuthConfiguration = this .createAppAuthConfiguration (builder );
156
+ final HashMap <String , String > additionalParametersMap = MapUtil .readableMapToHashMap (additionalParameters );
157
+
158
+ // when serviceConfiguration is provided, we don't need to hit up the OpenID well-known id endpoint
159
+ if (serviceConfiguration != null || mServiceConfiguration .get () != null ) {
160
+ try {
161
+ final AuthorizationServiceConfiguration serviceConfig = mServiceConfiguration .get () != null ? mServiceConfiguration .get () : createAuthorizationServiceConfiguration (serviceConfiguration );
162
+ registerWithConfiguration (
163
+ serviceConfig ,
164
+ appAuthConfiguration ,
165
+ redirectUris ,
166
+ responseTypes ,
167
+ grantTypes ,
168
+ subjectType ,
169
+ tokenEndpointAuthMethod ,
170
+ additionalParametersMap ,
171
+ promise
172
+ );
173
+ } catch (Exception e ) {
174
+ promise .reject ("Failed to refresh token" , e .getMessage ());
175
+ }
176
+ } else {
177
+ final Uri issuerUri = Uri .parse (issuer );
178
+ AuthorizationServiceConfiguration .fetchFromUrl (
179
+ buildConfigurationUriFromIssuer (issuerUri ),
180
+ new AuthorizationServiceConfiguration .RetrieveConfigurationCallback () {
181
+ public void onFetchConfigurationCompleted (
182
+ @ Nullable AuthorizationServiceConfiguration fetchedConfiguration ,
183
+ @ Nullable AuthorizationException ex ) {
184
+ if (ex != null ) {
185
+ promise .reject ("Failed to fetch configuration" , getErrorMessage (ex ));
186
+ return ;
187
+ }
188
+
189
+ mServiceConfiguration .set (fetchedConfiguration );
190
+
191
+ registerWithConfiguration (
192
+ fetchedConfiguration ,
193
+ appAuthConfiguration ,
194
+ redirectUris ,
195
+ responseTypes ,
196
+ grantTypes ,
197
+ subjectType ,
198
+ tokenEndpointAuthMethod ,
199
+ additionalParametersMap ,
200
+ promise
201
+ );
202
+ }
203
+ },
204
+ builder );
205
+ }
206
+ }
207
+
133
208
@ ReactMethod
134
209
public void authorize (
135
210
String issuer ,
@@ -150,10 +225,6 @@ public void authorize(
150
225
final AppAuthConfiguration appAuthConfiguration = this .createAppAuthConfiguration (builder );
151
226
final HashMap <String , String > additionalParametersMap = MapUtil .readableMapToHashMap (additionalParameters );
152
227
153
- if (clientSecret != null ) {
154
- additionalParametersMap .put ("client_secret" , clientSecret );
155
- }
156
-
157
228
// store args in private fields for later use in onActivityResult handler
158
229
this .promise = promise ;
159
230
this .dangerouslyAllowInsecureHttpRequests = dangerouslyAllowInsecureHttpRequests ;
@@ -345,6 +416,64 @@ public void onTokenRequestCompleted(
345
416
}
346
417
}
347
418
419
+ /*
420
+ * Perform dynamic client registration with the provided configuration
421
+ */
422
+ private void registerWithConfiguration (
423
+ final AuthorizationServiceConfiguration serviceConfiguration ,
424
+ final AppAuthConfiguration appAuthConfiguration ,
425
+ final ReadableArray redirectUris ,
426
+ final ReadableArray responseTypes ,
427
+ final ReadableArray grantTypes ,
428
+ final String subjectType ,
429
+ final String tokenEndpointAuthMethod ,
430
+ final Map <String , String > additionalParametersMap ,
431
+ final Promise promise
432
+ ) {
433
+ final Context context = this .reactContext ;
434
+
435
+ AuthorizationService authService = new AuthorizationService (context , appAuthConfiguration );
436
+
437
+ RegistrationRequest .Builder registrationRequestBuilder =
438
+ new RegistrationRequest .Builder (
439
+ serviceConfiguration ,
440
+ arrayToUriList (redirectUris )
441
+ )
442
+ .setAdditionalParameters (additionalParametersMap );
443
+
444
+ if (responseTypes != null ) {
445
+ registrationRequestBuilder .setResponseTypeValues (arrayToList (responseTypes ));
446
+ }
447
+
448
+ if (grantTypes != null ) {
449
+ registrationRequestBuilder .setGrantTypeValues (arrayToList (grantTypes ));
450
+ }
451
+
452
+ if (subjectType != null ) {
453
+ registrationRequestBuilder .setSubjectType (subjectType );
454
+ }
455
+
456
+ if (tokenEndpointAuthMethod != null ) {
457
+ registrationRequestBuilder .setTokenEndpointAuthenticationMethod (tokenEndpointAuthMethod );
458
+ }
459
+
460
+ RegistrationRequest registrationRequest = registrationRequestBuilder .build ();
461
+
462
+ AuthorizationService .RegistrationResponseCallback registrationResponseCallback = new AuthorizationService .RegistrationResponseCallback () {
463
+ @ Override
464
+ public void onRegistrationRequestCompleted (@ Nullable RegistrationResponse response , @ Nullable AuthorizationException ex ) {
465
+ if (response != null ) {
466
+ WritableMap map = RegistrationResponseFactory .registrationResponseToMap (response );
467
+ promise .resolve (map );
468
+ } else {
469
+ promise .reject ("Failed to refresh token" , getErrorMessage (ex ));
470
+ }
471
+ }
472
+ };
473
+
474
+ authService .performRegistrationRequest (registrationRequest , registrationResponseCallback );
475
+ }
476
+
348
477
/*
349
478
* Authorize user with the provided configuration
350
479
*/
@@ -487,6 +616,9 @@ private void parseHeaderMap (ReadableMap headerMap) {
487
616
if (headerMap == null ) {
488
617
return ;
489
618
}
619
+ if (headerMap .hasKey ("register" ) && headerMap .getType ("register" ) == ReadableType .Map ) {
620
+ this .registrationRequestHeaders = MapUtil .readableMapToHashMap (headerMap .getMap ("register" ));
621
+ }
490
622
if (headerMap .hasKey ("authorize" ) && headerMap .getType ("authorize" ) == ReadableType .Map ) {
491
623
this .authorizationRequestHeaders = MapUtil .readableMapToHashMap (headerMap .getMap ("authorize" ));
492
624
}
@@ -527,6 +659,28 @@ private String arrayToString(ReadableArray array) {
527
659
return strBuilder .toString ();
528
660
}
529
661
662
+ /*
663
+ * Create a string list from an array of strings
664
+ */
665
+ private List <String > arrayToList (ReadableArray array ) {
666
+ ArrayList <String > list = new ArrayList <>();
667
+ for (int i = 0 ; i < array .size (); i ++) {
668
+ list .add (array .getString (i ));
669
+ }
670
+ return list ;
671
+ }
672
+
673
+ /*
674
+ * Create a Uri list from an array of strings
675
+ */
676
+ private List <Uri > arrayToUriList (ReadableArray array ) {
677
+ ArrayList <Uri > list = new ArrayList <>();
678
+ for (int i = 0 ; i < array .size (); i ++) {
679
+ list .add (Uri .parse (array .getString (i )));
680
+ }
681
+ return list ;
682
+ }
683
+
530
684
/*
531
685
* Create an App Auth configuration using the provided connection builder
532
686
*/
0 commit comments