Skip to content

Consider a OneTimeToken integration with Spring MVC #15623

@marcusdacoregio

Description

@marcusdacoregio

This would simplify the resolution of an OneTimeToken. Currently, a OneTimeTokenService should be injected and a OneTimeTokenAuthenticationRequest must be created manually.

@GetMapping("/ott/generate")
public String generateOtt(Authentication authentication, Model model) {
	OneTimeTokenAuthenticationRequest request = new OneTimeTokenAuthenticationRequest(authentication.getName());
	OneTimeToken oneTimeToken = this.oneTimeTokenService.generate(request);
	model.addAttribute("oneTimeToken", oneTimeToken);
	return "ott-generate";
}

For example, authenticated users might want to generate a One-Time Token to log in from another device, let's say a TV, where it is very unlikely that they want to type their long passwords. This is also great to avoid typing your password into a device that might be public, like a hotel TV or a cybercafe computer.

One idea is to provide a HandlerMethodArgumentResolver that resolves the OneTimeToken parameter.

class OneTimeTokenRequestArgumentResolver implements HandlerMethodArgumentResolver {

	private final SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();

	private final AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return OneTimeToken.class.equals(parameter.getParameterType());
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		OneTimeTokenService oneTimeTokenService = this.applicationContext.getBean(OneTimeTokenService.class);
		}
		Authentication authentication = this.securityContextHolderStrategy.getContext().getAuthentication();
		if (this.authenticationTrustResolver.isAnonymous(authentication)) {
			return null;
		}
		OneTimeTokenAuthenticationRequest request = new OneTimeTokenAuthenticationRequest(authentication.getName());
		return oneTimeTokenService.generate(request);
	}

}
@GetMapping("/ott/generate")
public String generateOtt(OneTimeToken oneTimeToken, Model model) {
	model.addAttribute("oneTimeToken", oneTimeToken);
	return "ott-generate";
}

We could also provide an additional annotation to allow customizing which OneTimeTokenService to use if the application has more than one.

@GetMapping("/ott/generate")
public String generateOtt(@GenerateOneTimeToken(oneTimeTokenServiceBeanName = "deviceOneTimeTokenService") OneTimeToken oneTimeToken, Model model) {
	model.addAttribute("oneTimeToken", oneTimeToken);
	return "ott-generate";
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: webAn issue in web modules (web, webmvc)type: enhancementA general enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions