1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
23
23
import java .util .Collections ;
24
24
import java .util .List ;
25
25
26
+ import com .nimbusds .jose .JWSAlgorithm ;
26
27
import com .nimbusds .jose .KeySourceException ;
27
28
import com .nimbusds .jose .jwk .ECKey ;
28
29
import com .nimbusds .jose .jwk .JWK ;
39
40
import org .mockito .invocation .InvocationOnMock ;
40
41
import org .mockito .stubbing .Answer ;
41
42
43
+ import org .springframework .core .convert .converter .Converter ;
42
44
import org .springframework .security .oauth2 .jose .TestJwks ;
43
45
import org .springframework .security .oauth2 .jose .TestKeys ;
44
46
import org .springframework .security .oauth2 .jose .jws .SignatureAlgorithm ;
51
53
import static org .mockito .BDDMockito .willAnswer ;
52
54
import static org .mockito .Mockito .mock ;
53
55
import static org .mockito .Mockito .spy ;
56
+ import static org .mockito .Mockito .verify ;
57
+ import static org .mockito .Mockito .verifyNoInteractions ;
54
58
55
59
/**
56
60
* Tests for {@link NimbusJwtEncoder}.
@@ -109,7 +113,7 @@ public void encodeWhenJwkSelectFailedThenThrowJwtEncodingException() throws Exce
109
113
110
114
@ Test
111
115
public void encodeWhenJwkMultipleSelectedThenThrowJwtEncodingException () throws Exception {
112
- RSAKey rsaJwk = TestJwks .DEFAULT_RSA_JWK ;
116
+ RSAKey rsaJwk = TestJwks .rsa (). algorithm ( JWSAlgorithm . RS256 ). build () ;
113
117
this .jwkList .add (rsaJwk );
114
118
this .jwkList .add (rsaJwk );
115
119
@@ -118,7 +122,7 @@ public void encodeWhenJwkMultipleSelectedThenThrowJwtEncodingException() throws
118
122
119
123
assertThatExceptionOfType (JwtEncodingException .class )
120
124
.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] " );
122
126
}
123
127
124
128
@ Test
@@ -291,6 +295,55 @@ public List<JWK> get(JWKSelector jwkSelector, SecurityContext context) {
291
295
assertThat (jwk1 .getKeyID ()).isNotEqualTo (jwk2 .getKeyID ());
292
296
}
293
297
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
+
294
347
private static final class JwkListResultCaptor implements Answer <List <JWK >> {
295
348
296
349
private List <JWK > result ;
0 commit comments