WebAuthnProcessingFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { if (postOnly && !HttpMethod.POST.matches(request.getMethod())) { throw new AuthenticationServiceException( "Authentication method not supported: " + request.getMethod()); } String credentialId = obtainCredentialId(request); if(StringUtils.isEmpty(credentialId)){ String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } else { String clientDataJSON = obtainClientDataJSON(request); String authenticatorData = obtainAuthenticatorData(request); String signature = obtainSignatureData(request); String clientExtensionsJSON = obtainClientExtensionsJSON(request); byte[] rawId = Base64Utils.decodeFromUrlSafeString(credentialId); byte[] rawClientData = Base64Utils.decodeFromUrlSafeString(clientDataJSON); byte[] rawAuthenticatorData = Base64Utils.decodeFromUrlSafeString(authenticatorData); byte[] signatureBytes = Base64Utils.decodeFromUrlSafeString(signature); ServerProperty serverProperty = serverPropertyProvider.provide(request); WebAuthnAuthenticationRequest webAuthnAuthenticationRequest = new WebAuthnAuthenticationRequest( rawId, rawClientData, rawAuthenticatorData, signatureBytes, clientExtensionsJSON ); WebAuthnAuthenticationParameters webAuthnAuthenticationParameters = new WebAuthnAuthenticationParameters( serverProperty, userVerificationStrategy.isUserVerificationRequired(), true ); AbstractAuthenticationToken authenticationToken = new WebAuthnAssertionAuthenticationToken(webAuthnAuthenticationRequest, webAuthnAuthenticationParameters, authorities); setDetails(request, authenticationToken); return this.getAuthenticationManager().authenticate(authenticationToken); } } WebAuthnProcessingFilter();  WebAuthnProcessingFilter(List<GrantedAuthority> authorities, ServerPropertyProvider serverPropertyProvider); @Override Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response); @Override void setPostOnly(boolean postOnly); String getCredentialIdParameter(); void setCredentialIdParameter(String credentialIdParameter); String getClientDataJSONParameter(); void setClientDataJSONParameter(String clientDataJSONParameter); String getAuthenticatorDataParameter(); void setAuthenticatorDataParameter(String authenticatorDataParameter); String getSignatureParameter(); void setSignatureParameter(String signatureParameter); String getClientExtensionsJSONParameter(); void setClientExtensionsJSONParameter(String clientExtensionsJSONParameter); ServerPropertyProvider getServerPropertyProvider(); void setServerPropertyProvider(ServerPropertyProvider serverPropertyProvider); static final String SPRING_SECURITY_FORM_CREDENTIAL_ID_KEY; static final String SPRING_SECURITY_FORM_CLIENT_DATA_JSON_KEY; static final String SPRING_SECURITY_FORM_AUTHENTICATOR_DATA_KEY; static final String SPRING_SECURITY_FORM_SIGNATURE_KEY; static final String SPRING_SECURITY_FORM_CLIENT_EXTENSIONS_JSON_KEY; }
@Test public void attemptAuthentication_test_with_username_password() { mockHttpServletRequest.setMethod("POST"); mockHttpServletRequest.setParameter("username", "username"); mockHttpServletRequest.setParameter("password", "password"); when(authenticationManager.authenticate(captor.capture())).thenReturn(null); target.attemptAuthentication(mockHttpServletRequest, mockHttpServletResponse); Authentication authenticationToken = captor.getValue(); assertThat(authenticationToken.getPrincipal()).isEqualTo("username"); assertThat(authenticationToken.getCredentials()).isEqualTo("password"); }
@Test public void attemptAuthentication_test_with_credential() { String credentialId = "AAhdofeLeQWG6Y6gwwytZKNCDFB1WaIgqDsOwVYR5UavKQhAti4ic9_Dz-_CQEPpN0To6hiDRSCvmFHXaG6HK5yvvhm4DJRVJXzSvZiq5NefbXSYIr2uUaKbsoBe1lulhNdL9dRt6Dkkp38uq02YIR5CDaoxD-HQgMsS667aWlhHVKE884Sq0d1VVgGTDb1ds-Py_H7CDqk9SDErb8-XtQ9L"; String clientDataJSON = "eyJjaGFsbGVuZ2UiOiJGT3JHWklmSFJfeURaSklydTVPdXBBIiwiaGFzaEFsZyI6IlMyNTYiLCJvcmlnaW4iOiJsb2NhbGhvc3QifQ"; String authenticatorData = "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MBAAABaQ"; String signature = "MEUCIGBYMUVg2KkMG7V7UEsGxUeKVaO8x587JyVoZkk6FmsgAiEA5XRKxlYe2Vpwn-JYEJhcEVJ3-0nYFG-JfheOk4rA3dc"; String clientExtensionsJSON = ""; ServerProperty serverProperty = mock(ServerProperty.class); mockHttpServletRequest.setMethod("POST"); mockHttpServletRequest.setServerName("example.com"); mockHttpServletRequest.setParameter("credentialId", credentialId); mockHttpServletRequest.setParameter("clientDataJSON", clientDataJSON); mockHttpServletRequest.setParameter("authenticatorData", authenticatorData); mockHttpServletRequest.setParameter("signature", signature); mockHttpServletRequest.setParameter("clientExtensionsJSON", clientExtensionsJSON); when(authenticationManager.authenticate(captor.capture())).thenReturn(null); when(serverPropertyProvider.provide(any())).thenReturn(serverProperty); target.attemptAuthentication(mockHttpServletRequest, mockHttpServletResponse); WebAuthnAssertionAuthenticationToken authenticationToken = (WebAuthnAssertionAuthenticationToken) captor.getValue(); verify(serverPropertyProvider).provide(mockHttpServletRequest); assertThat(authenticationToken.getPrincipal()).isNull(); assertThat(authenticationToken.getCredentials()).isInstanceOf(WebAuthnAuthenticationRequest.class); assertThat(authenticationToken.getCredentials().getCredentialId()).isEqualTo(Base64UrlUtil.decode(credentialId)); assertThat(authenticationToken.getCredentials().getClientDataJSON()).isEqualTo(Base64UrlUtil.decode(clientDataJSON)); assertThat(authenticationToken.getCredentials().getAuthenticatorData()).isEqualTo(Base64UrlUtil.decode(authenticatorData)); assertThat(authenticationToken.getCredentials().getSignature()).isEqualTo(Base64UrlUtil.decode(signature)); assertThat(authenticationToken.getCredentials().getClientExtensionsJSON()).isEqualTo(clientExtensionsJSON); assertThat(authenticationToken.getParameters().getServerProperty()).isEqualTo(serverProperty); }
@Test(expected = AuthenticationServiceException.class) public void attemptAuthentication_test_with_wrong_port() { mockHttpServletRequest.setMethod("GET"); when(authenticationManager.authenticate(captor.capture())).thenReturn(null); target.attemptAuthentication(mockHttpServletRequest, mockHttpServletResponse); }