Skip to content

Commit 699e9bf

Browse files
committed
testing for multiple classes of redirect URIs
1 parent 38710bd commit 699e9bf

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,11 @@
2828
import java.util.concurrent.TimeUnit;
2929

3030
import org.apache.commons.codec.binary.Base64;
31-
import org.apache.http.MethodNotSupportedException;
3231
import org.apache.http.client.HttpClient;
3332
import org.apache.http.impl.client.HttpClientBuilder;
3433
import org.mitre.oauth2.model.ClientDetailsEntity;
35-
import org.mitre.oauth2.model.SystemScope;
3634
import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
35+
import org.mitre.oauth2.model.SystemScope;
3736
import org.mitre.oauth2.repository.OAuth2ClientRepository;
3837
import org.mitre.oauth2.repository.OAuth2TokenRepository;
3938
import org.mitre.oauth2.service.ClientDetailsEntityService;
@@ -54,6 +53,8 @@
5453
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
5554
import org.springframework.stereotype.Service;
5655
import org.springframework.web.client.RestTemplate;
56+
import org.springframework.web.util.UriComponents;
57+
import org.springframework.web.util.UriComponentsBuilder;
5758

5859
import com.google.common.base.Strings;
5960
import com.google.common.cache.CacheBuilder;
@@ -281,6 +282,34 @@ private void checkHeartMode(ClientDetailsEntity client) {
281282
throw new IllegalArgumentException("[HEART mode] All clients must have a key registered");
282283
}
283284

285+
// make sure our redirect URIs each fit one of the allowed categories
286+
if (client.getRedirectUris() != null) {
287+
boolean localhost = false;
288+
boolean remoteHttps = false;
289+
boolean customScheme = false;
290+
for (String uri : client.getRedirectUris()) {
291+
UriComponents components = UriComponentsBuilder.fromUriString(uri).build();
292+
if (components.getScheme().equals("http")) {
293+
// http scheme, check for localhost
294+
if (components.getHost().equals("localhost") || components.getHost().equals("127.0.0.1")) {
295+
localhost = true;
296+
} else {
297+
throw new IllegalArgumentException("[HEART mode] Can't have an http redirect URI on non-local host");
298+
}
299+
} else if (components.getScheme().equals("https")) {
300+
remoteHttps = true;
301+
} else {
302+
customScheme = true;
303+
}
304+
}
305+
306+
// now we make sure the client has a URI in only one of each of the three categories
307+
if (!((localhost ^ remoteHttps ^ customScheme)
308+
&& !(localhost && remoteHttps && customScheme))) {
309+
throw new IllegalArgumentException("[HEART mode] Can't have more than one class of redirect URI");
310+
}
311+
}
312+
284313
}
285314
}
286315

openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,12 @@ public void heartMode_authcode_invalidGrants() {
377377
grantTypes.add("client_credentials");
378378
client.setGrantTypes(grantTypes);
379379

380+
client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY);
381+
382+
client.setRedirectUris(Sets.newHashSet("https://foo.bar/"));
383+
384+
client.setJwksUri("https://foo.bar/jwks");
385+
380386
service.saveNewClient(client);
381387

382388
}
@@ -392,6 +398,12 @@ public void heartMode_implicit_invalidGrants() {
392398
grantTypes.add("client_credentials");
393399
client.setGrantTypes(grantTypes);
394400

401+
client.setTokenEndpointAuthMethod(AuthMethod.NONE);
402+
403+
client.setRedirectUris(Sets.newHashSet("https://foo.bar/"));
404+
405+
client.setJwksUri("https://foo.bar/jwks");
406+
395407
service.saveNewClient(client);
396408

397409
}
@@ -407,6 +419,10 @@ public void heartMode_clientcreds_invalidGrants() {
407419
grantTypes.add("implicit");
408420
client.setGrantTypes(grantTypes);
409421

422+
client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY);
423+
424+
client.setJwksUri("https://foo.bar/jwks");
425+
410426
service.saveNewClient(client);
411427

412428
}
@@ -422,6 +438,10 @@ public void heartMode_authcode_authMethod() {
422438

423439
client.setTokenEndpointAuthMethod(AuthMethod.SECRET_POST);
424440

441+
client.setRedirectUris(Sets.newHashSet("https://foo.bar/"));
442+
443+
client.setJwksUri("https://foo.bar/jwks");
444+
425445
service.saveNewClient(client);
426446

427447
}
@@ -437,6 +457,10 @@ public void heartMode_implicit_authMethod() {
437457

438458
client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY);
439459

460+
client.setRedirectUris(Sets.newHashSet("https://foo.bar/"));
461+
462+
client.setJwksUri("https://foo.bar/jwks");
463+
440464
service.saveNewClient(client);
441465

442466
}
@@ -451,6 +475,10 @@ public void heartMode_clientcreds_authMethod() {
451475
client.setGrantTypes(grantTypes);
452476

453477
client.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
478+
479+
client.setRedirectUris(Sets.newHashSet("https://foo.bar/"));
480+
481+
client.setJwksUri("https://foo.bar/jwks");
454482

455483
service.saveNewClient(client);
456484

@@ -564,4 +592,43 @@ public void heartMode_validAuthcodeClient() {
564592
assertThat(client.getClientSecret(), is(nullValue()));
565593
}
566594

595+
@Test(expected = IllegalArgumentException.class)
596+
public void heartMode_nonLocalHttpRedirect() {
597+
Mockito.when(config.isHeartMode()).thenReturn(true);
598+
599+
ClientDetailsEntity client = new ClientDetailsEntity();
600+
Set<String> grantTypes = new LinkedHashSet<>();
601+
grantTypes.add("authorization_code");
602+
grantTypes.add("refresh_token");
603+
client.setGrantTypes(grantTypes);
604+
605+
client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY);
606+
607+
client.setRedirectUris(Sets.newHashSet("http://foo.bar/"));
608+
609+
client.setJwksUri("https://foo.bar/jwks");
610+
611+
service.saveNewClient(client);
612+
613+
}
614+
615+
@Test(expected = IllegalArgumentException.class)
616+
public void heartMode_multipleRedirectClass() {
617+
Mockito.when(config.isHeartMode()).thenReturn(true);
618+
619+
ClientDetailsEntity client = new ClientDetailsEntity();
620+
Set<String> grantTypes = new LinkedHashSet<>();
621+
grantTypes.add("authorization_code");
622+
grantTypes.add("refresh_token");
623+
client.setGrantTypes(grantTypes);
624+
625+
client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY);
626+
627+
client.setRedirectUris(Sets.newHashSet("http://localhost/", "https://foo.bar", "foo://bar"));
628+
629+
client.setJwksUri("https://foo.bar/jwks");
630+
631+
service.saveNewClient(client);
632+
633+
}
567634
}

0 commit comments

Comments
 (0)