Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JwtIssuerValidator should use URL.toExternalForm #6073

Closed
rwinch opened this issue Nov 13, 2018 · 2 comments
Closed

JwtIssuerValidator should use URL.toExternalForm #6073

rwinch opened this issue Nov 13, 2018 · 2 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: bug A general bug
Milestone

Comments

@rwinch
Copy link
Member

rwinch commented Nov 13, 2018

Summary

There is a bug in JwtIssuerValidator because it uses URL.equals which is bad for two reasons:

  • URL.equals is slow because it resolves the hostname From the Javadoc

Compares this URL for equality with another object.
If the given object is not a URL then this method immediately returns false.

Two URL objects are equal if they have the same protocol, reference equivalent hosts, have the same port number on the host, and the same file and fragment of the file.

Two hosts are considered equivalent if both host names can be resolved into the same IP addresses; else if either host name can't be resolved, the host names must be equal without regard to case; or both host names equal to null.

Since hosts comparison requires name resolution, this operation is a blocking operation.

Note: The defined behavior for equals is known to be inconsistent with virtual hosting in HTTP

  • URL.equals is inconsistent because the hostname may resolve to different IP addresses when the host can resolve to multiple ipaddresses. For example, the following test will fail:
@Test
public void urls() throws Exception {
	URL issuer = new URL("https://dev-816256.oktapreview.com/oauth2/default");
	while(true) {
		assertThat(issuer).isEqualTo(new URL("https://dev-816256.oktapreview.com/oauth2/default"));
		Thread.sleep(TimeUnit.SECONDS.toMillis(1));
	}
}

Related: oktadev/okta-spring-webflux-react-example#9

@rwinch rwinch added type: bug A general bug in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) labels Nov 13, 2018
@rwinch rwinch added this to the 5.1.2 milestone Nov 13, 2018
@jzheaux jzheaux modified the milestones: 5.1.2, 5.2.0.M1 Nov 13, 2018
jzheaux added a commit that referenced this issue Nov 13, 2018
Converts URLs to Strings before comparing them. Uses toString(),
which delegates to toExternalForm().

Fixes: gh-6073
jzheaux added a commit to jzheaux/spring-security that referenced this issue Nov 13, 2018
Since StringOrURI is a valid issuer, MappedJwtClaimSetConverter and
JwtIssuerValidator no longer assume it.

Issue: spring-projectsgh-6073
jzheaux added a commit that referenced this issue Nov 13, 2018
Since StringOrURI is a valid issuer, MappedJwtClaimSetConverter and
JwtIssuerValidator no longer assume it.

Issue: gh-6073
jzheaux added a commit that referenced this issue Nov 13, 2018
Update documentation that indicated the iss claim is proactively
coerced into a URL.

Issue: gh-6073
jzheaux added a commit that referenced this issue Nov 13, 2018
Update documentation that indicated the iss claim is proactively
coerced into a URL.

Issue: gh-6073
jer051 pushed a commit to jer051/spring-security that referenced this issue Nov 21, 2018
Converts URLs to Strings before comparing them. Uses toString(),
which delegates to toExternalForm().

Fixes: spring-projectsgh-6073
jer051 pushed a commit to jer051/spring-security that referenced this issue Nov 21, 2018
Since StringOrURI is a valid issuer, MappedJwtClaimSetConverter and
JwtIssuerValidator no longer assume it.

Issue: spring-projectsgh-6073
jer051 pushed a commit to jer051/spring-security that referenced this issue Nov 21, 2018
Update documentation that indicated the iss claim is proactively
coerced into a URL.

Issue: spring-projectsgh-6073
@mathias-ewald
Copy link

Is there a workaround applicable to spring boot 2.1.0.RELEASE?

@jzheaux
Copy link
Contributor

jzheaux commented Nov 26, 2018

@mathias-ewald This has been backported to 5.1.2, so the easiest may be to update your pom once that releases.

Barring that, though, you can switch out the JwtIssuerValidator for your own:

@Bean
public JwtDecoder jwtDecoder() {
    NimbusJwtDecoderJwkSupport jwtDecoder = (NimbusJwtDecoderJwkSupport)
        JwtDecoders.fromOidcIssuerLocation("https://your-issuer-location");

    OAuth2TokenValidator<Jwt> withoutIssuer = JwtValidators.createDefault();
    OAuth2TokenValidator<Jwt> yourIssuerValidator = // ... your implementation
    DelegatingOAuth2TokenValidator<Jwt> jwtValidator = 
        new DelegatingOAuth2TokenValidator<Jwt>(withoutIssuer, yourIssuerValidator);
    jwtDecoder.setJwtValidator(jwtValidator);

    return jwtDecoder;
}

While not precisely the same scenario, we demoed an example of customizing validation at Spring One that you might find helpful as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants