Spring Security check codes increases

First, the codes generated using kaptcha

kaptcha dependencies

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

 

kaptcha configuration class

@Configuration
public class KaptchaConfig {
    @Bean
    public Producer captcha(){
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "120");
        properties.setProperty("kaptcha.image.height", "45");
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        Config config = new Config(properties);

        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

 

In ValidateCodeControllerthe verification picture to increase access interface

@RestController
 public  class ValidateCodeController {

@Autowired
private Producer captchaProducer;

@GetMapping("/captcha.jpg")
public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    String text = captchaProducer.createText();
    request.getSession().setAttribute("captcha", text);
    BufferedImage image = captchaProducer.createImage(text);
    ImageIO.write(image, "JPEG", response.getOutputStream());
}

 

Second, increasing the filter check codes

Spring security verification form is through a filter chain  to complete, we add a filter codes should be inserted  before, if the PIN verification is not passed, return directly without checking the account password. UsernamePasswordAuthenticationFilter UsernamePasswordAuthenticationFilter

Spring Security itself does not provide a verification code verification interface or an abstract class, developers need to realize themselves. Below implement a  do verification code filter, the filter will inherit , this can ensure that each request the filter is called only once, because we call once is enough. ValidateCodeFilter OncePerRequestFilter

 

@Component
public class ValidateCodeFilter extends OncePerRequestFilter {

    @Autowired
    private MyAuthenticationFailureHandler authenticationFailureHandler;

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    @Override
    protected  void doFilterInternal (the HttpServletRequest Request, the HttpServletResponse Response, the FilterChain filterChain) throws ServletException, IOException {
         // authentication / request interface is the form, check codes only need to match the time of authentication interfaces 
        IF (StringUtils.equals ( "/ authentication / form ", Request.getRequestURI ()) && 
                StringUtils.equalsAnyIgnoreCase (request.getMethod (), " POST " )) {
             the try {
                validate(new ServletWebRequest(request));
            } The catch (ValidateCodeException E) {
             // when the validation fails, the failure of the processor to handle authenticationFailureHandler.onAuthenticationFailure (Request, Response, E); 
                return ;
            }
        }
        // no abnormal That verification is successful, release. 
        filterChain.doFilter (request, response);

    }

    Private  void the validate (ServletWebRequest Request) throws ValidateCodeException {
         // Get the session codes from the 
        Object captcha = sessionStrategy.getAttribute (Request, "captcha" );
         // received from the client's codes 
        String captchaParam = request.getParameter ( " captcha " );

        IF (StringUtils.isEmpty (captchaParam)) {
             the throw  new new ValidateCodeException ( "codes can not be empty" );
        }

        IF (captcha == null ) {
             the throw  new new ValidateCodeException ( "codes does not exist" );
        }

        IF (! StringUtils.equalsAnyIgnoreCase (captcha.toString (), captchaParam)) {
             the throw  new new ValidateCodeException ( "authentication code mismatch" );
        }
        // After the verification is successful, is removed from the session codes 
        sessionStrategy.removeAttribute (Request, "captcha" );
    }
}

 

Third, the filter is inserted  before UsernamePasswordAuthenticationFilter

 

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
        .formLogin ()
        .loginPage ( "myLogin.html")    // login page 
        .loginProcessingUrl ( "/ authentication / form") // front-end to back-end initiates an authentication path 
        .successHandler (authenticationSuccessHandler)
        .failureHandler(authenticationFailureHandler)
        .and()
        .authorizeRequests()
        .antMatchers ( "myLogin.html", "/captcha.jpg"). permitAll ()    // When a match to / authentication / require, without having to authentication 
        .anyRequest ()
        .authenticated()
        .and()
        .csrf().disable();
}

 

Front page:

 

<form action="/authentication/form" method="post">
    账户:<input type="text" name="username" /> <br>
    密码:<input type="text" name="password" /> <br>
    验证码:<input type="text" name="captcha"> <img src="/captcha.jpg" alt="#">
    <br>
    <input type="submit" value="登录">
</form>

 

 

 

Guess you like

Origin www.cnblogs.com/africancu/p/11870241.html