Skip to content

Commit 399a715

Browse files
author
Kadi Kraman
authored
Merge pull request #470 from aeirola/fix-android-multiple-providers
Fix android multiple providers
2 parents 52ed9e7 + 350bd31 commit 399a715

File tree

2 files changed

+86
-43
lines changed

2 files changed

+86
-43
lines changed

Example/App.js

+71-28
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,87 @@
11
import React, { useState, useCallback, useMemo } from 'react';
22
import { UIManager, LayoutAnimation, Alert } from 'react-native';
3-
import { authorize, refresh, revoke } from 'react-native-app-auth';
3+
import { authorize, refresh, revoke, prefetchConfiguration } from 'react-native-app-auth';
44
import { Page, Button, ButtonContainer, Form, FormLabel, FormValue, Heading } from './components';
55

66
UIManager.setLayoutAnimationEnabledExperimental &&
77
UIManager.setLayoutAnimationEnabledExperimental(true);
88

99
type State = {
1010
hasLoggedInOnce: boolean,
11+
provider: ?string,
1112
accessToken: ?string,
1213
accessTokenExpirationDate: ?string,
1314
refreshToken: ?string
1415
};
1516

16-
const config = {
17-
issuer: 'https://demo.identityserver.io',
18-
clientId: 'native.code',
19-
redirectUrl: 'io.identityserver.demo:/oauthredirect',
20-
additionalParameters: {},
21-
scopes: ['openid', 'profile', 'email', 'offline_access']
22-
23-
// serviceConfiguration: {
24-
// authorizationEndpoint: 'https://demo.identityserver.io/connect/authorize',
25-
// tokenEndpoint: 'https://demo.identityserver.io/connect/token',
26-
// revocationEndpoint: 'https://demo.identityserver.io/connect/revoke'
27-
// }
17+
const configs = {
18+
identityserver: {
19+
issuer: 'https://demo.identityserver.io',
20+
clientId: 'native.code',
21+
redirectUrl: 'io.identityserver.demo:/oauthredirect',
22+
additionalParameters: {},
23+
scopes: ['openid', 'profile', 'email', 'offline_access'],
24+
25+
// serviceConfiguration: {
26+
// authorizationEndpoint: 'https://demo.identityserver.io/connect/authorize',
27+
// tokenEndpoint: 'https://demo.identityserver.io/connect/token',
28+
// revocationEndpoint: 'https://demo.identityserver.io/connect/revoke'
29+
// }
30+
},
31+
auth0: {
32+
// From https://openidconnect.net/
33+
issuer: 'https://samples.auth0.com',
34+
clientId: 'kbyuFDidLLm280LIwVFiazOqjO3ty8KH',
35+
redirectUrl: 'https://openidconnect.net/callback',
36+
additionalParameters: {},
37+
scopes: ['openid', 'profile', 'email', 'phone', 'address'],
38+
39+
// serviceConfiguration: {
40+
// authorizationEndpoint: 'https://samples.auth0.com/authorize',
41+
// tokenEndpoint: 'https://samples.auth0.com/oauth/token',
42+
// revocationEndpoint: 'https://samples.auth0.com/oauth/revoke'
43+
// }
44+
}
2845
};
2946

3047
const defaultAuthState = {
3148
hasLoggedInOnce: false,
49+
provider: '',
3250
accessToken: '',
3351
accessTokenExpirationDate: '',
3452
refreshToken: ''
3553
};
3654

3755
export default () => {
3856
const [authState, setAuthState] = useState(defaultAuthState);
39-
40-
const handleAuthorize = useCallback(async () => {
41-
try {
42-
const newAuthState = await authorize(config);
43-
44-
setAuthState({
45-
hasLoggedInOnce: true,
46-
...newAuthState
47-
});
48-
49-
} catch (error) {
50-
Alert.alert('Failed to log in', error.message);
51-
}
52-
}, [authState]);
57+
React.useEffect(() => {
58+
prefetchConfiguration({
59+
warmAndPrefetchChrome: true,
60+
...configs.identityserver
61+
});
62+
}, []);
63+
64+
const handleAuthorize = useCallback(
65+
async provider => {
66+
try {
67+
const config = configs[provider];
68+
const newAuthState = await authorize(config);
69+
70+
setAuthState({
71+
hasLoggedInOnce: true,
72+
provider: provider,
73+
...newAuthState
74+
});
75+
} catch (error) {
76+
Alert.alert('Failed to log in', error.message);
77+
}
78+
},
79+
[authState]
80+
);
5381

5482
const handleRefresh = useCallback(async () => {
5583
try {
84+
const config = configs[authState.provider];
5685
const newAuthState = await refresh(config, {
5786
refreshToken: authState.refreshToken
5887
});
@@ -70,12 +99,14 @@ export default () => {
7099

71100
const handleRevoke = useCallback(async () => {
72101
try {
102+
const config = configs[authState.provider];
73103
await revoke(config, {
74104
tokenToRevoke: authState.accessToken,
75105
sendClientId: true
76106
});
77107

78108
setAuthState({
109+
provider: '',
79110
accessToken: '',
80111
accessTokenExpirationDate: '',
81112
refreshToken: ''
@@ -87,6 +118,7 @@ export default () => {
87118

88119
const showRevoke = useMemo(() => {
89120
if (authState.accessToken) {
121+
const config = configs[authState.provider];
90122
if (config.issuer || config.serviceConfiguration.revocationEndpoint) {
91123
return true;
92124
}
@@ -113,7 +145,18 @@ export default () => {
113145

114146
<ButtonContainer>
115147
{!authState.accessToken ? (
116-
<Button onPress={handleAuthorize} text="Authorize" color="#DA2536" />
148+
<>
149+
<Button
150+
onPress={() => handleAuthorize('identityserver')}
151+
text="Authorize IdentityServer"
152+
color="#DA2536"
153+
/>
154+
<Button
155+
onPress={() => handleAuthorize('auth0')}
156+
text="Authorize Auth0"
157+
color="#DA2536"
158+
/>
159+
</>
117160
) : null}
118161
{!!authState.refreshToken ? (
119162
<Button onPress={handleRefresh} text="Refresh" color="#24C2CB" />

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

+15-15
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import java.util.HashMap;
5252
import java.util.List;
5353
import java.util.Map;
54-
import java.util.concurrent.atomic.AtomicReference;
54+
import java.util.concurrent.ConcurrentHashMap;
5555
import java.util.concurrent.CountDownLatch;
5656

5757
public class RNAppAuthModule extends ReactContextBaseJavaModule implements ActivityEventListener {
@@ -67,7 +67,7 @@ public class RNAppAuthModule extends ReactContextBaseJavaModule implements Activ
6767
private Map<String, String> tokenRequestHeaders = null;
6868
private Map<String, String> additionalParametersMap;
6969
private String clientSecret;
70-
private final AtomicReference<AuthorizationServiceConfiguration> mServiceConfiguration = new AtomicReference<>();
70+
private final ConcurrentHashMap<String, AuthorizationServiceConfiguration> mServiceConfigurations = new ConcurrentHashMap<>();
7171
private boolean isPrefetched = false;
7272

7373
public RNAppAuthModule(ReactApplicationContext reactContext) {
@@ -97,15 +97,15 @@ public void prefetchConfiguration(
9797
final CountDownLatch fetchConfigurationLatch = new CountDownLatch(1);
9898

9999
if(!isPrefetched) {
100-
if (serviceConfiguration != null && mServiceConfiguration.get() == null) {
100+
if (serviceConfiguration != null && !mServiceConfigurations.containsKey(issuer)) {
101101
try {
102-
mServiceConfiguration.set(createAuthorizationServiceConfiguration(serviceConfiguration));
102+
mServiceConfigurations.put(issuer, createAuthorizationServiceConfiguration(serviceConfiguration));
103103
isPrefetched = true;
104104
fetchConfigurationLatch.countDown();
105105
} catch (Exception e) {
106106
promise.reject("configuration_error", "Failed to convert serviceConfiguration", e);
107107
}
108-
} else if (mServiceConfiguration.get() == null) {
108+
} else if (!mServiceConfigurations.containsKey(issuer)) {
109109
final Uri issuerUri = Uri.parse(issuer);
110110
AuthorizationServiceConfiguration.fetchFromUrl(
111111
buildConfigurationUriFromIssuer(issuerUri),
@@ -117,7 +117,7 @@ public void onFetchConfigurationCompleted(
117117
promise.reject("service_configuration_fetch_error", "Failed to fetch configuration", ex);
118118
return;
119119
}
120-
mServiceConfiguration.set(fetchedConfiguration);
120+
mServiceConfigurations.put(issuer, fetchedConfiguration);
121121
isPrefetched = true;
122122
fetchConfigurationLatch.countDown();
123123
}
@@ -157,9 +157,9 @@ public void register(
157157
final HashMap<String, String> additionalParametersMap = MapUtil.readableMapToHashMap(additionalParameters);
158158

159159
// when serviceConfiguration is provided, we don't need to hit up the OpenID well-known id endpoint
160-
if (serviceConfiguration != null || mServiceConfiguration.get() != null) {
160+
if (serviceConfiguration != null || mServiceConfigurations.containsKey(issuer)) {
161161
try {
162-
final AuthorizationServiceConfiguration serviceConfig = mServiceConfiguration.get() != null ? mServiceConfiguration.get() : createAuthorizationServiceConfiguration(serviceConfiguration);
162+
final AuthorizationServiceConfiguration serviceConfig = mServiceConfigurations.containsKey(issuer)? mServiceConfigurations.get(issuer) : createAuthorizationServiceConfiguration(serviceConfiguration);
163163
registerWithConfiguration(
164164
serviceConfig,
165165
appAuthConfiguration,
@@ -187,7 +187,7 @@ public void onFetchConfigurationCompleted(
187187
return;
188188
}
189189

190-
mServiceConfiguration.set(fetchedConfiguration);
190+
mServiceConfigurations.put(issuer, fetchedConfiguration);
191191

192192
registerWithConfiguration(
193193
fetchedConfiguration,
@@ -234,9 +234,9 @@ public void authorize(
234234
this.clientAuthMethod = clientAuthMethod;
235235

236236
// when serviceConfiguration is provided, we don't need to hit up the OpenID well-known id endpoint
237-
if (serviceConfiguration != null || mServiceConfiguration.get() != null) {
237+
if (serviceConfiguration != null || mServiceConfigurations.containsKey(issuer)) {
238238
try {
239-
final AuthorizationServiceConfiguration serviceConfig = mServiceConfiguration.get() != null ? mServiceConfiguration.get() : createAuthorizationServiceConfiguration(serviceConfiguration);
239+
final AuthorizationServiceConfiguration serviceConfig = mServiceConfigurations.containsKey(issuer)? mServiceConfigurations.get(issuer) : createAuthorizationServiceConfiguration(serviceConfiguration);
240240
authorizeWithConfiguration(
241241
serviceConfig,
242242
appAuthConfiguration,
@@ -264,7 +264,7 @@ public void onFetchConfigurationCompleted(
264264
return;
265265
}
266266

267-
mServiceConfiguration.set(fetchedConfiguration);
267+
mServiceConfigurations.put(issuer, fetchedConfiguration);
268268

269269
authorizeWithConfiguration(
270270
fetchedConfiguration,
@@ -315,9 +315,9 @@ public void refresh(
315315
this.additionalParametersMap = additionalParametersMap;
316316

317317
// when serviceConfiguration is provided, we don't need to hit up the OpenID well-known id endpoint
318-
if (serviceConfiguration != null || mServiceConfiguration.get() != null) {
318+
if (serviceConfiguration != null || mServiceConfigurations.containsKey(issuer)) {
319319
try {
320-
final AuthorizationServiceConfiguration serviceConfig = mServiceConfiguration.get() != null ? mServiceConfiguration.get() : createAuthorizationServiceConfiguration(serviceConfiguration);
320+
final AuthorizationServiceConfiguration serviceConfig = mServiceConfigurations.containsKey(issuer) ? mServiceConfigurations.get(issuer) : createAuthorizationServiceConfiguration(serviceConfiguration);
321321
refreshWithConfiguration(
322322
serviceConfig,
323323
appAuthConfiguration,
@@ -348,7 +348,7 @@ public void onFetchConfigurationCompleted(
348348
return;
349349
}
350350

351-
mServiceConfiguration.set(fetchedConfiguration);
351+
mServiceConfigurations.put(issuer, fetchedConfiguration);
352352

353353
refreshWithConfiguration(
354354
fetchedConfiguration,

0 commit comments

Comments
 (0)