Skip to content

Commit e63b482

Browse files
authored
Merge pull request #414 from webauthn4j/make-fido-conformance-test-tool-pass-again
Make FIDO conformance test tool pass again
2 parents d1f837a + f6f7140 commit e63b482

File tree

45 files changed

+36
-2831
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+36
-2831
lines changed

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/fido/server/endpoint/FidoServerAssertionOptionsEndpointFilter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
import com.webauthn4j.springframework.security.challenge.ChallengeRepository;
2727
import com.webauthn4j.springframework.security.options.AssertionOptionsProvider;
2828
import com.webauthn4j.util.Base64UrlUtil;
29-
import org.springframework.security.core.Authentication;
30-
import org.springframework.security.core.context.SecurityContextHolder;
29+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3130
import org.springframework.util.Assert;
3231

3332
import javax.servlet.http.HttpServletRequest;
3433
import java.io.IOException;
3534
import java.io.InputStream;
3635
import java.io.UncheckedIOException;
36+
import java.util.Collections;
3737
import java.util.List;
3838
import java.util.stream.Collectors;
3939

@@ -86,8 +86,8 @@ protected ServerResponse processRequest(HttpServletRequest request) {
8686
objectConverter.getJsonConverter().readValue(inputStream, ServerPublicKeyCredentialGetOptionsRequest.class);
8787
Challenge challenge = serverEndpointFilterUtil.encodeUserVerification(new DefaultChallenge(), serverRequest.getUserVerification());
8888
challengeRepository.saveChallenge(challenge, request);
89-
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
90-
PublicKeyCredentialRequestOptions options = optionsProvider.getAssertionOptions(request, authentication);
89+
//TODO: UsernamePasswordAuthenticationToken should not be used here in this way
90+
PublicKeyCredentialRequestOptions options = optionsProvider.getAssertionOptions(request, new UsernamePasswordAuthenticationToken(serverRequest.getUsername(), null, Collections.emptyList()));
9191
List<ServerPublicKeyCredentialDescriptor> credentials = options.getAllowCredentials().stream()
9292
.map(credential -> new ServerPublicKeyCredentialDescriptor(credential.getType(), Base64UrlUtil.encodeToString(credential.getId()), credential.getTransports()))
9393
.collect(Collectors.toList());

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/fido/server/endpoint/FidoServerAttestationOptionsEndpointFilter.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
import com.webauthn4j.springframework.security.challenge.ChallengeRepository;
2727
import com.webauthn4j.springframework.security.options.AttestationOptionsProvider;
2828
import com.webauthn4j.util.Base64UrlUtil;
29-
import org.springframework.security.core.Authentication;
30-
import org.springframework.security.core.context.SecurityContextHolder;
29+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
3130
import org.springframework.util.Assert;
3231

3332
import javax.servlet.http.HttpServletRequest;
3433
import java.io.IOException;
3534
import java.io.InputStream;
3635
import java.io.UncheckedIOException;
3736
import java.nio.ByteBuffer;
37+
import java.util.Collections;
3838
import java.util.List;
3939
import java.util.UUID;
4040
import java.util.stream.Collectors;
@@ -85,12 +85,12 @@ protected ServerResponse processRequest(HttpServletRequest request) {
8585
try {
8686
ServerPublicKeyCredentialCreationOptionsRequest serverRequest = objectConverter.getJsonConverter()
8787
.readValue(inputStream, ServerPublicKeyCredentialCreationOptionsRequest.class);
88-
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
89-
String username = authentication.getName();
88+
String username = serverRequest.getUsername();
9089
String displayName = serverRequest.getDisplayName();
9190
Challenge challenge = serverEndpointFilterUtil.encodeUsername(new DefaultChallenge(), username);
9291
challengeRepository.saveChallenge(challenge, request);
93-
PublicKeyCredentialCreationOptions attestationOptions = optionsProvider.getAttestationOptions(request, authentication);
92+
//TODO: UsernamePasswordAuthenticationToken should not be used here in this way
93+
PublicKeyCredentialCreationOptions attestationOptions = optionsProvider.getAttestationOptions(request, new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()));
9494
String userHandle;
9595
if (attestationOptions.getUser() == null) {
9696
userHandle = Base64UrlUtil.encodeToString(generateUserHandle());

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/fido/server/endpoint/FidoServerAttestationResultEndpointFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ protected ServerResponse processRequest(HttpServletRequest request) {
118118
WebAuthnAuthenticatorImpl webAuthnAuthenticator =
119119
new WebAuthnAuthenticatorImpl(
120120
"Authenticator",
121-
userDetails,
121+
loginUsername,
122122
attestationObject.getAuthenticatorData().getAttestedCredentialData(),
123123
attestationObject.getAttestationStatement(),
124124
attestationObject.getAuthenticatorData().getSignCount()

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/webauthn/sample/SampleWebApplication.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
package com.webauthn4j.springframework.security.webauthn.sample;
1818

1919
import com.webauthn4j.springframework.security.webauthn.sample.app.config.AppConfig;
20-
import com.webauthn4j.springframework.security.webauthn.sample.domain.config.DomainConfig;
21-
import com.webauthn4j.springframework.security.webauthn.sample.infrastructure.config.InfrastructureConfig;
2220
import org.springframework.boot.SpringApplication;
2321
import org.springframework.boot.SpringBootConfiguration;
2422
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -27,7 +25,7 @@
2725
/**
2826
* SampleWebApplication
2927
*/
30-
@Import({AppConfig.class, DomainConfig.class, InfrastructureConfig.class})
28+
@Import({AppConfig.class})
3129
@SpringBootConfiguration
3230
@EnableAutoConfiguration
3331
public class SampleWebApplication {

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/webauthn/sample/app/config/WebSecurityBeanConfig.java

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.webauthn4j.metadata.*;
2828
import com.webauthn4j.metadata.converter.jackson.WebAuthnMetadataJSONModule;
2929
import com.webauthn4j.springframework.security.WebAuthnRegistrationRequestValidator;
30+
import com.webauthn4j.springframework.security.authenticator.InMemoryWebAuthnAuthenticatorManager;
31+
import com.webauthn4j.springframework.security.authenticator.WebAuthnAuthenticatorManager;
3032
import com.webauthn4j.springframework.security.authenticator.WebAuthnAuthenticatorService;
3133
import com.webauthn4j.springframework.security.challenge.ChallengeRepository;
3234
import com.webauthn4j.springframework.security.challenge.HttpSessionChallengeRepository;
@@ -53,35 +55,35 @@
5355
import org.springframework.core.io.Resource;
5456
import org.springframework.core.io.ResourceLoader;
5557
import org.springframework.core.io.support.ResourcePatternUtils;
56-
import org.springframework.security.access.AccessDeniedException;
5758
import org.springframework.security.authentication.AuthenticationTrustResolver;
5859
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
5960
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
60-
import org.springframework.security.core.AuthenticationException;
6161
import org.springframework.security.core.userdetails.UserDetailsService;
6262
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
6363
import org.springframework.security.crypto.password.PasswordEncoder;
64-
import org.springframework.security.web.AuthenticationEntryPoint;
65-
import org.springframework.security.web.access.AccessDeniedHandler;
66-
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
67-
import org.springframework.security.web.access.DelegatingAccessDeniedHandler;
68-
import org.springframework.security.web.authentication.*;
69-
import org.springframework.security.web.authentication.logout.ForwardLogoutSuccessHandler;
70-
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
71-
import org.springframework.security.web.csrf.InvalidCsrfTokenException;
72-
import org.springframework.security.web.csrf.MissingCsrfTokenException;
64+
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
65+
import org.springframework.security.provisioning.UserDetailsManager;
7366
import org.springframework.web.client.RestTemplate;
7467

7568
import java.io.IOException;
7669
import java.security.cert.X509Certificate;
7770
import java.util.ArrayList;
7871
import java.util.Arrays;
79-
import java.util.LinkedHashMap;
8072
import java.util.List;
8173

8274
@Configuration
8375
public class WebSecurityBeanConfig {
8476

77+
@Bean
78+
public WebAuthnAuthenticatorManager webAuthnAuthenticatorManager(){
79+
return new InMemoryWebAuthnAuthenticatorManager();
80+
}
81+
82+
@Bean
83+
public UserDetailsManager userDetailsManager(){
84+
return new InMemoryUserDetailsManager();
85+
}
86+
8587
@Bean
8688
public WebAuthnRegistrationRequestValidator webAuthnRegistrationRequestValidator(WebAuthnManager webAuthnManager, ServerPropertyProvider serverPropertyProvider) {
8789
return new WebAuthnRegistrationRequestValidator(webAuthnManager, serverPropertyProvider);
@@ -242,57 +244,4 @@ public ObjectConverter objectConverter() {
242244
return new ObjectConverter(jsonMapper, cborMapper);
243245
}
244246

245-
246-
@Bean
247-
public AuthenticationSuccessHandler authenticationSuccessHandler() {
248-
return new ForwardAuthenticationSuccessHandler("/api/status/200");
249-
}
250-
251-
@Bean
252-
public AuthenticationFailureHandler authenticationFailureHandler() {
253-
LinkedHashMap<Class<? extends AuthenticationException>, AuthenticationFailureHandler> authenticationFailureHandlers = new LinkedHashMap<>();
254-
255-
// authenticator error handler
256-
ForwardAuthenticationFailureHandler authenticationFailureHandler = new ForwardAuthenticationFailureHandler("/api/status/401");
257-
authenticationFailureHandlers.put(AuthenticationException.class, authenticationFailureHandler);
258-
259-
// default error handler
260-
AuthenticationFailureHandler defaultAuthenticationFailureHandler = new ForwardAuthenticationFailureHandler("/api/status/401");
261-
262-
return new DelegatingAuthenticationFailureHandler(authenticationFailureHandlers, defaultAuthenticationFailureHandler);
263-
}
264-
265-
@Bean
266-
public LogoutSuccessHandler logoutSuccessHandler() {
267-
return new ForwardLogoutSuccessHandler("/api/status/200");
268-
}
269-
270-
@Bean
271-
public AccessDeniedHandler accessDeniedHandler() {
272-
LinkedHashMap<Class<? extends AccessDeniedException>, AccessDeniedHandler> errorHandlers = new LinkedHashMap<>();
273-
274-
// invalid csrf authenticator error handler
275-
AccessDeniedHandlerImpl invalidCsrfTokenErrorHandler = new AccessDeniedHandlerImpl();
276-
invalidCsrfTokenErrorHandler.setErrorPage("/api/status/403");
277-
errorHandlers.put(InvalidCsrfTokenException.class, invalidCsrfTokenErrorHandler);
278-
279-
// missing csrf authenticator error handler
280-
AccessDeniedHandlerImpl missingCsrfTokenErrorHandler = new AccessDeniedHandlerImpl();
281-
missingCsrfTokenErrorHandler.setErrorPage("/api/status/403");
282-
errorHandlers.put(MissingCsrfTokenException.class, missingCsrfTokenErrorHandler);
283-
284-
// default error handler
285-
AccessDeniedHandlerImpl defaultErrorHandler = new AccessDeniedHandlerImpl();
286-
defaultErrorHandler.setErrorPage("/api/status/403");
287-
288-
return new DelegatingAccessDeniedHandler(errorHandlers, defaultErrorHandler);
289-
}
290-
291-
@Bean
292-
public AuthenticationEntryPoint authenticationEntryPoint() {
293-
LoginUrlAuthenticationEntryPoint authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/api/status/401");
294-
authenticationEntryPoint.setUseForward(true);
295-
return authenticationEntryPoint;
296-
}
297-
298247
}

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/webauthn/sample/app/config/WebSecurityConfig.java

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,18 @@
3535
import com.webauthn4j.springframework.security.options.AttestationOptionsProvider;
3636
import com.webauthn4j.springframework.security.server.ServerPropertyProvider;
3737
import com.webauthn4j.springframework.security.webauthn.sample.app.security.SampleUsernameNotFoundHandler;
38-
import com.webauthn4j.springframework.security.webauthn.sample.domain.component.UserManager;
3938
import org.springframework.beans.factory.annotation.Autowired;
4039
import org.springframework.context.annotation.Bean;
4140
import org.springframework.context.annotation.Configuration;
4241
import org.springframework.context.annotation.Import;
4342
import org.springframework.http.HttpMethod;
4443
import org.springframework.security.authentication.AuthenticationManager;
45-
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
4644
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
4745
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
4846
import org.springframework.security.config.annotation.web.builders.WebSecurity;
4947
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
5048
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
51-
import org.springframework.security.web.AuthenticationEntryPoint;
52-
import org.springframework.security.web.access.AccessDeniedHandler;
53-
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
54-
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
55-
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
49+
import org.springframework.security.provisioning.UserDetailsManager;
5650
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
5751
import org.springframework.security.web.session.SessionManagementFilter;
5852

@@ -68,24 +62,6 @@
6862

6963
private static final String ADMIN_ROLE = "ADMIN";
7064

71-
@Autowired
72-
private AuthenticationSuccessHandler authenticationSuccessHandler;
73-
74-
@Autowired
75-
private AuthenticationFailureHandler authenticationFailureHandler;
76-
77-
@Autowired
78-
private AccessDeniedHandler accessDeniedHandler;
79-
80-
@Autowired
81-
private LogoutSuccessHandler logoutSuccessHandler;
82-
83-
@Autowired
84-
private AuthenticationEntryPoint authenticationEntryPoint;
85-
86-
@Autowired
87-
private DaoAuthenticationProvider daoAuthenticationProvider;
88-
8965
@Autowired
9066
private WebAuthnAuthenticatorService authenticatorService;
9167

@@ -96,7 +72,7 @@
9672
private WebAuthnRegistrationRequestValidator webAuthnRegistrationRequestValidator;
9773

9874
@Autowired
99-
private UserManager userManager;
75+
private UserDetailsManager userDetailsManager;
10076

10177
@Autowired
10278
private ObjectConverter objectConverter;
@@ -164,8 +140,8 @@ protected void configure(HttpSecurity http) throws Exception {
164140

165141

166142
FidoServerAttestationOptionsEndpointFilter fidoServerAttestationOptionsEndpointFilter = new FidoServerAttestationOptionsEndpointFilter(objectConverter, attestationOptionsProvider, challengeRepository);
167-
FidoServerAttestationResultEndpointFilter fidoServerAttestationResultEndpointFilter = new FidoServerAttestationResultEndpointFilter(objectConverter, userManager, webAuthnAuthenticatorManager, webAuthnRegistrationRequestValidator);
168-
fidoServerAttestationResultEndpointFilter.setUsernameNotFoundHandler(new SampleUsernameNotFoundHandler(userManager));
143+
FidoServerAttestationResultEndpointFilter fidoServerAttestationResultEndpointFilter = new FidoServerAttestationResultEndpointFilter(objectConverter, userDetailsManager, webAuthnAuthenticatorManager, webAuthnRegistrationRequestValidator);
144+
fidoServerAttestationResultEndpointFilter.setUsernameNotFoundHandler(new SampleUsernameNotFoundHandler(userDetailsManager));
169145
FidoServerAssertionOptionsEndpointFilter fidoServerAssertionOptionsEndpointFilter = new FidoServerAssertionOptionsEndpointFilter(objectConverter, assertionOptionsProvider, challengeRepository);
170146
FidoServerAssertionResultEndpointFilter fidoServerAssertionResultEndpointFilter = new FidoServerAssertionResultEndpointFilter(objectConverter, serverPropertyProvider);
171147
fidoServerAssertionResultEndpointFilter.setAuthenticationManager(authenticationManagerBean());
@@ -175,19 +151,6 @@ protected void configure(HttpSecurity http) throws Exception {
175151
http.addFilterAfter(fidoServerAssertionOptionsEndpointFilter, SessionManagementFilter.class);
176152
http.addFilterAfter(fidoServerAssertionResultEndpointFilter, SessionManagementFilter.class);
177153

178-
179-
// // FIDO Server Endpoints
180-
// http.apply(fidoServer())
181-
// .fidoServerAttestationOptionsEndpoint()
182-
// .and()
183-
// .fidoServerAttestationResultEndpointConfig()
184-
// .webAuthnRegistrationRequestValidator(webAuthnRegistrationRequestValidator)
185-
// .usernameNotFoundHandler(new SampleUsernameNotFoundHandler(userManager))
186-
// .and()
187-
// .fidoServerAssertionOptionsEndpointConfig()
188-
// .and()
189-
// .fidoServerAssertionResultEndpoint();
190-
191154
// Authorization
192155
http.authorizeRequests()
193156
.mvcMatchers("/").permitAll()
@@ -200,13 +163,6 @@ protected void configure(HttpSecurity http) throws Exception {
200163
.mvcMatchers("/api/admin/**").hasRole(ADMIN_ROLE)
201164
.anyRequest().fullyAuthenticated();
202165

203-
http.sessionManagement()
204-
.sessionAuthenticationFailureHandler(authenticationFailureHandler);
205-
206-
http.exceptionHandling()
207-
.authenticationEntryPoint(authenticationEntryPoint)
208-
.accessDeniedHandler(accessDeniedHandler);
209-
210166
//TODO:
211167
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
212168

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/webauthn/sample/app/security/SampleUsernameNotFoundHandler.java

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,22 @@
1717
package com.webauthn4j.springframework.security.webauthn.sample.app.security;
1818

1919
import com.webauthn4j.springframework.security.fido.server.endpoint.UsernameNotFoundHandler;
20-
import com.webauthn4j.springframework.security.webauthn.sample.domain.component.UserManager;
21-
import com.webauthn4j.springframework.security.webauthn.sample.domain.entity.UserEntity;
20+
import org.springframework.security.core.userdetails.User;
21+
import org.springframework.security.provisioning.UserDetailsManager;
2222

2323
import java.util.Collections;
2424

2525
public class SampleUsernameNotFoundHandler implements UsernameNotFoundHandler {
2626

27-
private final UserManager userManager;
27+
private final UserDetailsManager userDetailsManager;
2828

29-
public SampleUsernameNotFoundHandler(UserManager userManager) {
30-
this.userManager = userManager;
29+
public SampleUsernameNotFoundHandler(UserDetailsManager userDetailsManager) {
30+
this.userDetailsManager = userDetailsManager;
3131
}
3232

3333
@Override
3434
public void onUsernameNotFound(String loginUsername) {
35-
byte[] userHandle = new byte[0]; //TODO
36-
UserEntity userEntity = new UserEntity();
37-
userEntity.setUserHandle(userHandle);
38-
userEntity.setEmailAddress(loginUsername);
39-
userEntity.setLastName("dummy");
40-
userEntity.setFirstName("dummy");
41-
userEntity.setSingleFactorAuthenticationAllowed(false);
42-
userEntity.setPassword("dummy");
43-
userEntity.setGroups(Collections.emptyList());
44-
userEntity.setAuthorities(Collections.emptyList());
45-
userEntity.setAuthenticators(Collections.emptyList());
46-
userManager.createUser(userEntity);
35+
User user = new User(loginUsername, "dummy", Collections.emptyList());
36+
userDetailsManager.createUser(user);
4737
}
4838
}

samples/fido-server-conformance-test-app/src/main/java/com/webauthn4j/springframework/security/webauthn/sample/app/util/modelmapper/StringToChallengeConverter.java

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)