Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

10
respostas

Criar captcha

Estou tentando configurar o captcha, conforme este link, mas não consegui. A configuração é por xml e a configuração aqui é por aquivos java. Como fazer ?

http://www.doanduyhai.com/blog/?p=1610

10 respostas

Um pré-requisito do texto é ter o Spring Security configurado. Você já fez?

Onde está <bean> no XML você pode criar um método que retorna o objeto e tem a anotação @Bean.

@Bean
public ReCaptchaAuthenticationFilter captcha(AuthenticationManager authenticationManager) {
ReCaptchaAuthenticationFilter recaptcha = new ReCaptchaAuthenticationFilter();
recaptcha.setAuthenticationManager(authenticationManager);
recaptcha.setFilterProcessesUrl("/authentication");
recaptcha.setPrivateKey("your_private_recaptcha_key");

SavedRequestAwareAuthenticationSuccessHandler success = new SavedRequestAwareAuthenticationSuccessHandler();
success.setAlwaysUseDefaultTargetUrl(true);
success.setDefaultTargetUrl("/home");
recaptcha.setAuthenticationSuccessHandler(success);

SimpleUrlAuthenticationFailureHandler failure = new SimpleUrlAuthenticationFailureHandler();
failure.setDefaultFailureUrl("/login?error=1");
recaptcha.setAuthenticationFailureHandler(failure);
return recaptcha;
}

Spring security, já está configurado no projeto.

Tenho dois arquivos:

primeiro:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityWebConfig extends WebSecurityConfigurerAdapter {

E este:

package br.com.netsoft;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringWebSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

}

Ele reclama desta linha do que você informou.

ReCaptchaAuthenticationFilter, Entendo que esteja faltando esta classe.

Ah, a classe pede alguns argumentos no construtor:

public RecaptchaAuthenticationFilter(
            RecaptchaValidator recaptchaValidator,
            RecaptchaProperties recaptcha,
            LoginFailuresManager failuresManager
    )

Está diferente do POST!

Não entendi....

No código do blog que você colocou no início, não tinha esse construtor.

A ta, então eu poderia usar o exemplo do link que postei ?

Isso!

Essa classe:

public class ReCaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter implements InitializingBean
{
    private final String CAPTCHA_CHALLENGE_FIELD = "recaptcha_challenge_field";
    private final String CAPTCHA_RESPONSE_FIELD = "recaptcha_response_field";
    private final ReCaptchaImpl reCaptcha;
    private String privateKey;
    private final Logger log = LoggerFactory.getLogger(ReCaptchaAuthenticationFilter.class);

    public ReCaptchaAuthenticationFilter() {
        this.reCaptcha = new ReCaptchaImpl();
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException
    {

        String reCaptchaChallenge = request.getParameter(CAPTCHA_CHALLENGE_FIELD);
        String reCaptchaResponse = request.getParameter(CAPTCHA_RESPONSE_FIELD);
        String remoteAddress = request.getRemoteAddr();

        if (!StringUtils.isEmpty(reCaptchaChallenge))
        {
            log.debug("ReCaptcha Challenge not null");
            if (!StringUtils.isEmpty(reCaptchaResponse))
            {
                log.debug("ReCaptcha Answser not null, call ReCaptcha to verify it");
                ReCaptchaResponse reCaptchaCheck = reCaptcha.checkAnswer(remoteAddress, reCaptchaChallenge, reCaptchaResponse);

                if (reCaptchaCheck.isValid())
                {
                    log.debug("ReCaptcha answer is valid, attempt authentication");
                    return super.attemptAuthentication(request, response);
                }
                else
                {
                    this.reCaptchaError(request, response, "ReCaptcha failed : " + reCaptchaCheck.getErrorMessage());
                    return null;
                }
            }
            else
            {
                this.reCaptchaError(request, response, "ReCaptcha failed : empty answer");
                return null;
            }

        }
        else
        {
            return super.attemptAuthentication(request, response);
        }
    }

    private void reCaptchaError(HttpServletRequest request, HttpServletResponse response, String errorMsg)
    {
        log.error("ReCaptcha failed : " + errorMsg);
        try
        {

            RequestDispatcher dispatcher = request.getRequestDispatcher("/login?error=2");

            dispatcher.forward(request, response);
        }
        catch (ServletException e)
        {
            throw new AuthenticationServiceException("ReCaptcha failed : " + errorMsg);
        }
        catch (IOException e)
        {
            throw new AuthenticationServiceException("Recaptcha failed : " + errorMsg);
        }
    }

    public void setPrivateKey(String privateKey)
    {
        this.privateKey = privateKey;
    }

    public void afterPropertiesSet()
    {
        if (StringUtils.isEmpty(this.privateKey))
        {
            throw new IllegalArgumentException("The 'privateKey' should be set for the bean type 'ReCaptchaAuthenticationFilter'");
        }
        else
        {
            reCaptcha.setPrivateKey(this.privateKey);
        }
    }
}

Consegui não...

A sua classe dá erro na própria classe e em outras classes deste código do git.

Alguma ajuda ?