Currently One Time Tokens are created and then the success handler is invoked even if the user does not exist. We should only generate a token and invoke the success handler if a user exists. We should also pass the user to the success handler so it can be used by the success handler without the need to look up the user again.
NOTE: Consider a resulthandler that does both success/failure. Failure is indicated by the ott not generated. Need a new method to pass in the UserDetails on success anyway. Failure should be handled the same as success so as not to reveal information to the end user so this helps to use ensure logic is the same and that a functional API can be used. Alternatively could have two methods on the new interface but might encourage users to handle the logic differently.
If user exists - [x] generate a new ott - [x] invoke success handler
If user does not exist - [x] do not generate ott - [x] do not invoke success handler - [ ] invoke failure handler - [x] log.debug ott not generated
Comment From: franticticktick
Hi @rwinch. It makes sense to do such a check in GenerateOneTimeTokenFilter
before generating the token itself. I can suggest this solution:
GenerateOneTimeTokenRequest generateRequest = this.requestResolver.resolve(request);
try {
User user = userDetailsService.loadUserByUsername(generateRequest.getUsername());
OneTimeToken ott = this.tokenService.generate(generateRequest);
if (generateRequest == null) {
filterChain.doFilter(request, response);
return;
}
this.tokenGenerationSuccessHandler.handle(request, response, ott);
} catch (UsernameNotFoundException ex) {
logger.debug("One time token not generated. User " + username + " is not found.");
throw new BadCredentialsException("Authentication failed");
}
This code should be placed in doFilterInternal
immediately after resolving generateRequest
. If this solution is suitable, I’m ready to prepare PR
Comment From: rwinch
Thank you @franticticktick! Would you be interested in submitting a PR that targets 6.4.x?