mkopylec / recaptcha-spring-boot-starter-samples

Sample applications demostrating how to work with Spring Boot starter for Google's reCAPTCHA
Apache License 2.0
3 stars 3 forks source link

Configuration is not enough #2

Closed z1key closed 7 years ago

z1key commented 7 years ago

I tried to integrate recaptcha to my Spring Security project and was struggled in configuring Beans. In your samples I can't see any understandable configs. It is very poor. Please Help me to configure LoginFailureHandler & LoginSuccessHandler Every time I got errors:

java.lang.IllegalArgumentException: Invalid login failure handler. Handler must be an instance of com.github.mkopylec.recaptcha.security.login.LoginFailuresCountingHandler but is org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler

mkopylec commented 7 years ago

The error is self explanatory. If you want to use custom authentication failure handler and recaptcha support together your custom authentication handler needs to extend LoginFailuresCountingHandler

z1key commented 7 years ago

I don't want to use custom Auth failure handler. The application doesn't start with default config. I tried to create @Component (s) with extends these Classes but afterwards was no success. It is why I asked to explain the configuration of Beans. The error appears when I modified SecurityConfig by this:

@Autowired
    private FormLoginConfigurerEnhancer enhancer;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/home", "/signup", "/restore-password*").permitAll()
                .antMatchers("/admin*").hasAnyRole("ADMIN", "SUPERADMIN")
                .anyRequest().authenticated()
            .and()
                .rememberMe()
                .key("key")
                .rememberMeServices(rememberMeServices())
                .tokenValiditySeconds(86400);
            enhancer.addRecaptchaSupport(http.formLogin()) // After this changes
                .loginPage("/login")
                .usernameParameter("j_username")
                .passwordParameter("j_password")
                .failureUrl("/login?error=true")
                .permitAll()
            .and()
                .csrf()
                .disable()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login")
                .invalidateHttpSession(true)
                .permitAll();
    }

====================================================== Then I modified like this:

@Autowired
private FormLoginConfigurerEnhancer enhancer;

@Autowired
private LoginFailuresCountingHandler failuresCountingHandler;

@Autowired
private LoginFailuresClearingHandler successHandler;

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers("/", "/home", "/signup", "/restore-password*").permitAll()
            .antMatchers("/admin*").hasAnyRole("ADMIN", "SUPERADMIN")
            .anyRequest().authenticated()
        .and()
            .rememberMe()
            .key("key")
            .rememberMeServices(rememberMeServices())
            .tokenValiditySeconds(86400);
        enhancer.addRecaptchaSupport(http.formLogin())
            .loginPage("/login")
            .successHandler(successHandler)
            .failureHandler(failuresCountingHandler)
            .usernameParameter("j_username")
            .passwordParameter("j_password")
            .failureUrl("/login?error=true")
            .permitAll()
        .and()
            .csrf()
            .disable()
        .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login")
            .invalidateHttpSession(true)
            .permitAll();
}

And added two @Components

@Component
public class AuthenticationSuccessHandler extends LoginFailuresClearingHandler {

    @Autowired
    public AuthenticationSuccessHandler(LoginFailuresManager failuresManager) {
        super(failuresManager);
    }
}
@Component
public class AuthenticationFailureHandler extends LoginFailuresCountingHandler {
    @Autowired
    public AuthenticationFailureHandler(LoginFailuresManager failuresManager, RecaptchaProperties recaptcha, RecaptchaAwareRedirectStrategy redirectStrategy) {
        super(failuresManager, recaptcha, redirectStrategy);
    }
}

Getting same error when start application. What I do wrong?

mkopylec commented 7 years ago

Thanks for the sample, I see what is your problem now. You don't have to create your own autentication handlers, just remove them (the @Components). To fix it just first add a login failure URL to application.yml file if you want a custom URL:

recaptcha.security.failure-url: /login?error=true

Then remove the following line from your security configuration:

...
.failureUrl("/login?error=true")
...
mkopylec commented 7 years ago

Your configuration should look like this:

@Autowired
private FormLoginConfigurerEnhancer enhancer;

//@Autowired
//private LoginFailuresCountingHandler failuresCountingHandler;

//@Autowired
//private LoginFailuresClearingHandler successHandler;

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
            .antMatchers("/", "/home", "/signup", "/restore-password*").permitAll()
            .antMatchers("/admin*").hasAnyRole("ADMIN", "SUPERADMIN")
            .anyRequest().authenticated()
        .and()
            .rememberMe()
            .key("key")
            .rememberMeServices(rememberMeServices())
            .tokenValiditySeconds(86400);
        enhancer.addRecaptchaSupport(http.formLogin())
            .loginPage("/login")
 //           .successHandler(successHandler)
 //           .failureHandler(failuresCountingHandler)
            .usernameParameter("j_username")
            .passwordParameter("j_password")
 //           .failureUrl("/login?error=true")
            .permitAll()
        .and()
            .csrf()
            .disable()
        .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login")
            .invalidateHttpSession(true)
            .permitAll();
}

The authentication handlers are automatically provided by the recaptcha starter.

z1key commented 7 years ago

Thank You so much! Now is working!