Today when I was implementing ReCaptcha (as if there is much to implement!), I thought it would be perfect to create an Aspect Annotation to automatically secure web methods with recaptcha.My solution is strongly based on the ReCaptcha implementation walkthrough that can be found here: http://kielczewski.eu/2015/07/spring-recaptcha-v2-form-validation/ If it interests you, you can get the full source code and a fully working spring boot example project at the following link, you should be able to instantly import it into Eclipse or STS: https://github.com/Traubenfuchs/loup-recaptchaJust start the project and go to localhost:8080/If you want to see it in action visit this page: http://loup.at:8080/loup-recaptcha-0.0.1/As this is my first Aspect Oriented Programming adventure I would like your opinion on my code. I am especially unsure about proper error handling and the proper invalid recaptcha response code.Here are the core classes:The Aspect itself, RecaptchaAspect.java:package at.loup.core.recaptcha;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.stereotype.Component;@Aspect@Componentclass RecaptchaAspect {    @Autowired    private RecaptchaValidator recaptchaValidatorImpl;    @Autowired    private HttpServletRequest request;    @Autowired    private HttpServletResponse response;    @Around(@annotation(at.loup.core.recaptcha.RecaptchaProtected))    public Object validateRecaptchaResponse(ProceedingJoinPoint joinPoint) throws Throwable {        if (recaptchaValidatorImpl.validate(request.getRemoteAddr(), request.getHeader(recaptcha-response))) {            return joinPoint.proceed();        } else {            response.setStatus(HttpStatus.CONFLICT.value());            response.getOutputStream().print(Recaptcha failed!);            return null;        }    }}The Annotation that is used to apply the Aspect to a method, RecaptchaProtected.java:package at.loup.core.recaptcha;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface RecaptchaProtected {}The interface for the recaptcha validator, RecaptchaValidator.java:package at.loup.core.recaptcha;// based on http://kielczewski.eu/2015/07/spring-recaptcha-v2-form-validation/public interface RecaptchaValidator {    boolean validate(String remoteIp, String response);}The implementation of the recaptcha validator, RecaptchaValidatorImpl.java:package at.loup.core.recaptcha;import java.util.Collection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap;import org.springframework.web.client.RestClientException;import org.springframework.web.client.RestTemplate;// based on http://kielczewski.eu/2015/07/spring-recaptcha-v2-form-validation/@Servicepublic class RecaptchaValidatorImpl implements RecaptchaValidator {    @Autowired    private RestTemplate restTemplate;    @Value(${recaptcha.secretkey})    private String recaptchaSecretKey;    @Override    public boolean validate(String remoteIp, String response) throws RestClientException {        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();        form.add(secret, recaptchaSecretKey);        form.add(remoteip, remoteIp);        form.add(response, response);        RecaptchaResponse recaptchaResponse = restTemplate                .postForEntity(https://www.google.com/recaptcha/api/siteverify, form, RecaptchaResponse.class)                .getBody();        return recaptchaResponse.getSuccess();    }}class RecaptchaResponse {    private boolean success;    private Collection<String> errorCodes;    public boolean getSuccess() {        return success;    }    public Collection<String> getErrorCodes() {        return errorCodes;    }}
AspectJ aspect for securing controller methods with ReCaptcha
java;spring;aspect oriented