11/* 
2-  * Copyright 2002-2021  the original author or authors. 
2+  * Copyright 2002-2025  the original author or authors. 
33 * 
44 * Licensed under the Apache License, Version 2.0 (the "License"); 
55 * you may not use this file except in compliance with the License. 
2323import  java .util .Collections ;
2424import  java .util .List ;
2525
26+ import  com .nimbusds .jose .JWSAlgorithm ;
2627import  com .nimbusds .jose .KeySourceException ;
2728import  com .nimbusds .jose .jwk .ECKey ;
2829import  com .nimbusds .jose .jwk .JWK ;
3940import  org .mockito .invocation .InvocationOnMock ;
4041import  org .mockito .stubbing .Answer ;
4142
43+ import  org .springframework .core .convert .converter .Converter ;
4244import  org .springframework .security .oauth2 .jose .TestJwks ;
4345import  org .springframework .security .oauth2 .jose .TestKeys ;
4446import  org .springframework .security .oauth2 .jose .jws .SignatureAlgorithm ;
5153import  static  org .mockito .BDDMockito .willAnswer ;
5254import  static  org .mockito .Mockito .mock ;
5355import  static  org .mockito .Mockito .spy ;
56+ import  static  org .mockito .Mockito .verify ;
57+ import  static  org .mockito .Mockito .verifyNoInteractions ;
5458
5559/** 
5660 * Tests for {@link NimbusJwtEncoder}. 
@@ -109,7 +113,7 @@ public void encodeWhenJwkSelectFailedThenThrowJwtEncodingException() throws Exce
109113
110114	@ Test 
111115	public  void  encodeWhenJwkMultipleSelectedThenThrowJwtEncodingException () throws  Exception  {
112- 		RSAKey  rsaJwk  = TestJwks .DEFAULT_RSA_JWK ;
116+ 		RSAKey  rsaJwk  = TestJwks .rsa (). algorithm ( JWSAlgorithm . RS256 ). build () ;
113117		this .jwkList .add (rsaJwk );
114118		this .jwkList .add (rsaJwk );
115119
@@ -118,7 +122,7 @@ public void encodeWhenJwkMultipleSelectedThenThrowJwtEncodingException() throws
118122
119123		assertThatExceptionOfType (JwtEncodingException .class )
120124			.isThrownBy (() -> this .jwtEncoder .encode (JwtEncoderParameters .from (jwsHeader , jwtClaimsSet )))
121- 			.withMessageContaining ("Found multiple JWK signing keys  for algorithm ' RS256' " );
125+ 			.withMessageContaining ("Failed to select a key since there are multiple  for the signing  algorithm [ RS256] " );
122126	}
123127
124128	@ Test 
@@ -291,6 +295,55 @@ public List<JWK> get(JWKSelector jwkSelector, SecurityContext context) {
291295		assertThat (jwk1 .getKeyID ()).isNotEqualTo (jwk2 .getKeyID ());
292296	}
293297
298+ 	@ Test 
299+ 	public  void  encodeWhenMultipleKeysThenJwkSelectorUsed () throws  Exception  {
300+ 		JWK  jwk  = TestJwks .rsa ().algorithm (JWSAlgorithm .RS256 ).build ();
301+ 		JWKSource <SecurityContext > jwkSource  = mock (JWKSource .class );
302+ 		given (jwkSource .get (any (), any ())).willReturn (List .of (jwk , jwk ));
303+ 		Converter <List <JWK >, JWK > selector  = mock (Converter .class );
304+ 		given (selector .convert (any ())).willReturn (TestJwks .DEFAULT_RSA_JWK );
305+ 
306+ 		NimbusJwtEncoder  jwtEncoder  = new  NimbusJwtEncoder (jwkSource );
307+ 		jwtEncoder .setJwkSelector (selector );
308+ 
309+ 		JwtClaimsSet  claims  = JwtClaimsSet .builder ().subject ("sub" ).build ();
310+ 		jwtEncoder .encode (JwtEncoderParameters .from (claims ));
311+ 
312+ 		verify (selector ).convert (any ());
313+ 	}
314+ 
315+ 	@ Test 
316+ 	public  void  encodeWhenSingleKeyThenJwkSelectorIsNotUsed () throws  Exception  {
317+ 		JWK  jwk  = TestJwks .rsa ().algorithm (JWSAlgorithm .RS256 ).build ();
318+ 		JWKSource <SecurityContext > jwkSource  = mock (JWKSource .class );
319+ 		given (jwkSource .get (any (), any ())).willReturn (List .of (jwk ));
320+ 		Converter <List <JWK >, JWK > selector  = mock (Converter .class );
321+ 
322+ 		NimbusJwtEncoder  jwtEncoder  = new  NimbusJwtEncoder (jwkSource );
323+ 		jwtEncoder .setJwkSelector (selector );
324+ 
325+ 		JwtClaimsSet  claims  = JwtClaimsSet .builder ().subject ("sub" ).build ();
326+ 		jwtEncoder .encode (JwtEncoderParameters .from (claims ));
327+ 
328+ 		verifyNoInteractions (selector );
329+ 	}
330+ 
331+ 	@ Test 
332+ 	public  void  encodeWhenNoKeysThenJwkSelectorIsNotUsed () throws  Exception  {
333+ 		JWKSource <SecurityContext > jwkSource  = mock (JWKSource .class );
334+ 		given (jwkSource .get (any (), any ())).willReturn (List .of ());
335+ 		Converter <List <JWK >, JWK > selector  = mock (Converter .class );
336+ 
337+ 		NimbusJwtEncoder  jwtEncoder  = new  NimbusJwtEncoder (jwkSource );
338+ 		jwtEncoder .setJwkSelector (selector );
339+ 
340+ 		JwtClaimsSet  claims  = JwtClaimsSet .builder ().subject ("sub" ).build ();
341+ 		assertThatExceptionOfType (JwtEncodingException .class )
342+ 			.isThrownBy (() -> jwtEncoder .encode (JwtEncoderParameters .from (claims )));
343+ 
344+ 		verifyNoInteractions (selector );
345+ 	}
346+ 
294347	private  static  final  class  JwkListResultCaptor  implements  Answer <List <JWK >> {
295348
296349		private  List <JWK > result ;
0 commit comments