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

Jwt decoding should support multiple algorithms #6883

Closed
rwinch opened this issue May 15, 2019 · 7 comments · Fixed by #7162

Comments

@rwinch
Copy link
Member

commented May 15, 2019

Summary

We should add a strategy where Jwt decoders can delegate to other Jwt decoders based upon the algorithm that is in the JWT that was passed into it. This would allow supporting multiple algorithms returned by an IdP as discussed in #5465 (comment)

A possible way to do this would be to have a JwtDecoder implementation that calls other JwtDecoders, though note this might require decoding the JWT twice.

@rwinch rwinch added this to the 5.2.x milestone May 15, 2019

@jzheaux jzheaux changed the title Add JwtDecoder implementation that supports multiple algorithms Jwt decoding should support multiple algorithms May 20, 2019

@dnl50

This comment has been minimized.

Copy link
Contributor

commented Jun 3, 2019

Would it be possible to implement a JwtDecoder that decodes the header of the given token first to determine the signing algorithm used. The signing algorithm would then be used to find a decoder that supports the signing algorithm.

public class DelegatingJwtDecoder implements JwtDecoder {

	private List<DelegatedJwtDecoder> decoders;

	@Override
	public Jwt decode(String token) throws JwtException {
		String decodedHeader = decodeHeader(token);
		String signingAlg = getSigningAlgorithm(decodedHeader);
		DelegatedJwtDecoder jwtDecoder = findDecoder(signingAlg);

		return jwtDecoder.decode(token);
	}

	private String decodeHeader(String token) {
		// decode the Base64 encoded header of the token
	}

	private String getSigningAlgorithm(String tokenHeader) {
		// get the algorithm from the token header
	}

	private DelegatedJwtDecoder findDecoderSupportingAlgorithm(String algorithm) {
		return decoders.stream()
				.filter(decoder -> decoder.supportsAlgorithm(algorithm))
				.findFirst()
				.orElseThrow(() -> new IllegalArgumentException("No decoder found that support the signing algorithm!"));
	}

}

The DelegatedJwtDecoder would have an additional boolean supportsAlgorithm(String algorithm) method which would receive the signing algorithm the given token was signed with.

public interface DelegatedJwtDecoder extends JwtDecoder {

	boolean supportsAlgorithm(String algorithm);

}
@jgrandja

This comment has been minimized.

Copy link
Collaborator

commented Jun 3, 2019

@dnl50 I believe the example implementation you provided is similar to what @rwinch has suggested. However, I don't believe we need to introduce a new interface DelegatedJwtDecoder with the additional operation supportsAlgorithm().

Instead, we would provide a new implementation of JwtDecoder which would be constructed with a Map of alg to JwtDecoder to allow for this. It might not be a Map but would have to provide this type of mapping.

@compfantasy

This comment has been minimized.

Copy link

commented Jun 8, 2019

According to spring security reference, the algorithm can be override by providing a JwtDecoder bean, but it doesn't work after I did that because the initialization of NimbusJwtDecoderJwkSupport locates at line 212 of OidcAuthorizationCodeAuthenticationProvider.java

@jgrandja

This comment has been minimized.

Copy link
Collaborator

commented Jun 10, 2019

@compfantasy The PR #6495 introduced support in 5.2.0.M2 for a configurable JWS algorithm via OidcIdTokenDecoderFactory.setJwsAlgorithmResolver() or ReactiveOidcIdTokenDecoderFactory.setJwsAlgorithmResolver().

NOTE: NimbusJwtDecoderJwkSupport is deprecated in favour of NimbusJwtDecoder, which is used/configured by OidcIdTokenDecoderFactory.

@compfantasy

This comment has been minimized.

Copy link

commented Jun 13, 2019

@jgrandja Does this mean that I just need upgrade current version of spring-security-oauth2-jose-5.1.4.RELEASE to 5.2.0.M2, then configure jwsAlgorithm in client registration? do you have a simple demo project regarding this change?thanks

@compfantasy

This comment has been minimized.

Copy link

commented Jul 18, 2019

@jgrandja I already upgraded the version of spring-security-oauth2-client and spring-secuirty-oauth2-core to 5.2.0.M2, I can see there is a class named OidcIdTokenDecoderFactory, but how can i use setJwsAlgorithmResolver() to make JwsAlgorithm working in the spring context? I tried to create a new OidcTokenDecoderFactory bean and set the JwsAlgorithm to RS512, it doesn't work, and I tried to create a new JwtDecoder bean, it doesn't work for me as well, very appreciate if you can help here.

@jgrandja

This comment has been minimized.

Copy link
Collaborator

commented Jul 19, 2019

@compfantasy Can you please put together a minimal sample so I can see what you have so far and share via a GitHub repository. This will be the most effective way to help resolve this for you.

@jzheaux jzheaux self-assigned this Jul 29, 2019

@jzheaux jzheaux modified the milestones: 5.2.x, 5.2.0.M4 Jul 29, 2019

jzheaux added a commit to jzheaux/spring-security that referenced this issue Jul 29, 2019
jzheaux added a commit to jzheaux/spring-security that referenced this issue Jul 31, 2019
jzheaux added a commit to jzheaux/spring-security that referenced this issue Jul 31, 2019

@jzheaux jzheaux modified the milestones: 5.2.0.M4, 5.2.0.RC1 Aug 5, 2019

jzheaux added a commit to jzheaux/spring-security that referenced this issue Aug 17, 2019
jzheaux added a commit to jzheaux/spring-security that referenced this issue Aug 20, 2019
jzheaux added a commit that referenced this issue Aug 20, 2019
kostya05983 added a commit to kostya05983/spring-security that referenced this issue Aug 26, 2019
fhanik added a commit to fhanik/spring-security that referenced this issue Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.