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.
@@ -87,7 +87,18 @@ public final class NimbusJwtEncoder implements JwtEncoder {
8787
8888 private final JWKSource <SecurityContext > jwkSource ;
8989
90- private Converter <List <JWK >, JWK > jwkSelector ;
90+ private Converter <List <JWK >, JWK > jwkSelector = (jwks )->{
91+ if (jwks .size () > 1 ) {
92+ throw new JwtEncodingException (String .format (
93+ "Failed to select a key since there are multiple for the signing algorithm [%s]; " +
94+ "please specify a selector in NimbusJwsEncoder#setJwkSelector" ,jwks .get (0 ).getAlgorithm ()));
95+ }
96+ if (jwks .isEmpty ()) {
97+ throw new JwtEncodingException (
98+ String .format (ENCODING_ERROR_MESSAGE_TEMPLATE , "Failed to select a JWK signing key" ));
99+ }
100+ return jwks .get (0 );
101+ };
91102
92103 /**
93104 * Constructs a {@code NimbusJwtEncoder} using the provided parameters.
@@ -97,9 +108,17 @@ public NimbusJwtEncoder(JWKSource<SecurityContext> jwkSource) {
97108 Assert .notNull (jwkSource , "jwkSource cannot be null" );
98109 this .jwkSource = jwkSource ;
99110 }
100-
111+ /**
112+ * Use this strategy to reduce the list of matching JWKs down to a since one.
113+ * <p> For example, you can call {@code setJwkSelector(List::getFirst)} in order
114+ * to have this encoder select the first match.
115+ *
116+ * <p> By default, the class with throw an exception if there is more than one result.
117+ * @since 6.5
118+ */
101119 public void setJwkSelector (Converter <List <JWK >, JWK > jwkSelector ) {
102- this .jwkSelector = jwkSelector ;
120+ if (null !=jwkSelector )
121+ this .jwkSelector = jwkSelector ;
103122 }
104123
105124 @ Override
@@ -130,22 +149,7 @@ private JWK selectJwk(JwsHeader headers) {
130149 throw new JwtEncodingException (String .format (ENCODING_ERROR_MESSAGE_TEMPLATE ,
131150 "Failed to select a JWK signing key -> " + ex .getMessage ()), ex );
132151 }
133-
134- if (null != this .jwkSelector ) {
135- return this .jwkSelector .convert (jwks );
136- }
137-
138- if (jwks .size () > 1 ) {
139- throw new JwtEncodingException (String .format (ENCODING_ERROR_MESSAGE_TEMPLATE ,
140- "Found multiple JWK signing keys for algorithm '" + headers .getAlgorithm ().getName () + "'" ));
141- }
142-
143- if (jwks .isEmpty ()) {
144- throw new JwtEncodingException (
145- String .format (ENCODING_ERROR_MESSAGE_TEMPLATE , "Failed to select a JWK signing key" ));
146- }
147-
148- return jwks .get (0 );
152+ return this .jwkSelector .convert (jwks );
149153 }
150154
151155 private String serialize (JwsHeader headers , JwtClaimsSet claims , JWK jwk ) {
0 commit comments