1717package org .springframework .security .web .webauthn .authentication ;
1818
1919import java .io .IOException ;
20+ import java .util .List ;
21+ import java .util .Map ;
2022
2123import jakarta .servlet .ServletException ;
2224import jakarta .servlet .http .HttpServletRequest ;
2325import jakarta .servlet .http .HttpServletResponse ;
26+ import org .jspecify .annotations .Nullable ;
2427import tools .jackson .databind .json .JsonMapper ;
2528
2629import org .springframework .core .ResolvableType ;
30+ import org .springframework .http .HttpInputMessage ;
2731import org .springframework .http .HttpMethod ;
32+ import org .springframework .http .HttpOutputMessage ;
2833import org .springframework .http .HttpStatus ;
34+ import org .springframework .http .MediaType ;
35+ import org .springframework .http .converter .AbstractSmartHttpMessageConverter ;
2936import org .springframework .http .converter .GenericHttpMessageConverter ;
37+ import org .springframework .http .converter .HttpMessageNotReadableException ;
38+ import org .springframework .http .converter .HttpMessageNotWritableException ;
3039import org .springframework .http .converter .SmartHttpMessageConverter ;
3140import org .springframework .http .converter .json .JacksonJsonHttpMessageConverter ;
3241import org .springframework .http .server .ServletServerHttpRequest ;
3847import org .springframework .security .web .authentication .HttpMessageConverterAuthenticationSuccessHandler ;
3948import org .springframework .security .web .authentication .HttpStatusEntryPoint ;
4049import org .springframework .security .web .context .HttpSessionSecurityContextRepository ;
41- import org .springframework .security .web .http .GenericHttpMessageConverterAdapter ;
4250import org .springframework .security .web .webauthn .api .AuthenticatorAssertionResponse ;
4351import org .springframework .security .web .webauthn .api .PublicKeyCredential ;
4452import org .springframework .security .web .webauthn .api .PublicKeyCredentialRequestOptions ;
7482 */
7583public class WebAuthnAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
7684
77- private GenericHttpMessageConverter <Object > converter = new GenericHttpMessageConverterAdapter <> (
78- new JacksonJsonHttpMessageConverter ( JsonMapper .builder ().addModule (new WebauthnJacksonModule ()).build () ));
85+ private SmartHttpMessageConverter <Object > converter = new JacksonJsonHttpMessageConverter (
86+ JsonMapper .builder ().addModule (new WebauthnJacksonModule ()).build ());
7987
8088 private PublicKeyCredentialRequestOptionsRepository requestOptionsRepository = new HttpSessionPublicKeyCredentialRequestOptionsRepository ();
8189
@@ -96,7 +104,7 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
96104 PublicKeyCredential <AuthenticatorAssertionResponse > publicKeyCredential = null ;
97105 try {
98106 publicKeyCredential = (PublicKeyCredential <AuthenticatorAssertionResponse >) this .converter
99- .read (resolvableType . getType (), getClass (), httpRequest );
107+ .read (resolvableType , httpRequest , null );
100108 }
101109 catch (Exception ex ) {
102110 throw new BadCredentialsException ("Unable to authenticate the PublicKeyCredential" , ex );
@@ -118,10 +126,12 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
118126 * {@code PublicKeyCredential<AuthenticatorAssertionResponse>} to the response. The
119127 * default is @{code MappingJackson2HttpMessageConverter}
120128 * @param converter the {@link GenericHttpMessageConverter} to use. Cannot be null.
129+ * @deprecated use {@link #setConverter(SmartHttpMessageConverter)}
121130 */
131+ @ Deprecated (forRemoval = true , since = "7.0" )
122132 public void setConverter (GenericHttpMessageConverter <Object > converter ) {
123133 Assert .notNull (converter , "converter cannot be null" );
124- this .converter = converter ;
134+ this .converter = new GenericHttpMessageConverterAdapter <>( converter ) ;
125135 }
126136
127137 /**
@@ -133,7 +143,7 @@ public void setConverter(GenericHttpMessageConverter<Object> converter) {
133143 */
134144 public void setConverter (SmartHttpMessageConverter <Object > converter ) {
135145 Assert .notNull (converter , "converter cannot be null" );
136- this .converter = new GenericHttpMessageConverterAdapter <>( converter ) ;
146+ this .converter = converter ;
137147 }
138148
139149 /**
@@ -147,4 +157,55 @@ public void setRequestOptionsRepository(PublicKeyCredentialRequestOptionsReposit
147157 this .requestOptionsRepository = requestOptionsRepository ;
148158 }
149159
160+ /**
161+ * Adapts a {@link GenericHttpMessageConverter} to a
162+ * {@link SmartHttpMessageConverter}.
163+ *
164+ * @param <T> The type
165+ * @author Rob Winch
166+ * @since 7.0
167+ */
168+ private static final class GenericHttpMessageConverterAdapter <T > extends AbstractSmartHttpMessageConverter <T > {
169+
170+ private final GenericHttpMessageConverter <T > delegate ;
171+
172+ private GenericHttpMessageConverterAdapter (GenericHttpMessageConverter <T > delegate ) {
173+ Assert .notNull (delegate , "delegate cannot be null" );
174+ this .delegate = delegate ;
175+ }
176+
177+ @ Override
178+ public boolean canRead (Class <?> clazz , @ Nullable MediaType mediaType ) {
179+ return this .delegate .canRead (clazz , mediaType );
180+ }
181+
182+ @ Override
183+ public boolean canWrite (Class <?> clazz , @ Nullable MediaType mediaType ) {
184+ return this .delegate .canWrite (clazz , mediaType );
185+ }
186+
187+ @ Override
188+ public List <MediaType > getSupportedMediaTypes () {
189+ return this .delegate .getSupportedMediaTypes ();
190+ }
191+
192+ @ Override
193+ public List <MediaType > getSupportedMediaTypes (Class <?> clazz ) {
194+ return this .delegate .getSupportedMediaTypes (clazz );
195+ }
196+
197+ @ Override
198+ protected void writeInternal (T t , ResolvableType type , HttpOutputMessage outputMessage ,
199+ @ Nullable Map <String , Object > hints ) throws IOException , HttpMessageNotWritableException {
200+ this .delegate .write (t , null , outputMessage );
201+ }
202+
203+ @ Override
204+ public T read (ResolvableType type , HttpInputMessage inputMessage , @ Nullable Map <String , Object > hints )
205+ throws IOException , HttpMessageNotReadableException {
206+ return this .delegate .read (type .getType (), null , inputMessage );
207+ }
208+
209+ }
210+
150211}
0 commit comments