6 spring boot security 验证码kaptcha和过滤(2)

在第一篇基础上,增加了出错处理

1、pom.xml中添加

        <!-- 验证码kaptcha-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

2、在WebSecurityConfig中添加

注意:相比于第一篇,修改了出错处理!!! 

同时添加了出错处理

 

 

package com.chenclass.xabest.config;

import com.chenclass.xabest.filter.OpenIdAuthenticationFilter;
import com.chenclass.xabest.security.CustomUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity // 注解开启Spring Security的功能
//WebSecurityConfigurerAdapter:重写它的方法来设置一些web的安全西街
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomUserService customUserService;


    @Autowired
    MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;
    /*@Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
*/
    @Bean
    public PasswordEncoder passwordEncoder() {     return new BCryptPasswordEncoder();
    }

    //md5不够安全,spring5 已结删除
   // @Bean
  //  public Md5PasswordEncoder passwordEncoder() {    return new Md5PasswordEncoder();    }
   // public Md5PasswordEncoder md5 = new Md5PasswordEncoder();

    protected void configure(HttpSecurity http) throws Exception {
        http.addFilter(openIdAuthenticationFilter());
        http
                .authorizeRequests()  //定义哪些url需要保护,哪些url不需要保护
                .antMatchers("/layuiadmin/**","/reg/**","/defaultKaptcha**","/login**").permitAll()    //定义不需要认证就可以访问
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")  //定义当需要用户登录时候,转到的登录页面
                .permitAll()
                .and().logout().logoutSuccessUrl("/login")   //注销
                .and()
                .logout()
                .permitAll();
               // .and().cors(); // 这句非常重要了;
        http.csrf().disable(); //
        http.formLogin()
                .defaultSuccessUrl("/index")
                .failureHandler(myAuthenctiationFailureHandler);
              //  .failureUrl("/login?error=true");
        http.headers().frameOptions().disable();  //解决 in a frame because it set 'X-Frame-Options' to 'deny'.陈锡爱20190511
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        /*BCryptPasswordEncoder passwordEncoder =new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("111");
        auth
                .inMemoryAuthentication()
                //    .withUser("user").password("111").roles("USER");
                .withUser("user").password(password).roles("USER");
       */
        auth.userDetailsService(customUserService).passwordEncoder(passwordEncoder());
        //在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为USER
    }


    /**
     * 自定义登陆验证接口
     */
    public OpenIdAuthenticationFilter openIdAuthenticationFilter() throws Exception {
        OpenIdAuthenticationFilter openIdAuthenticationFilter = new OpenIdAuthenticationFilter();
        openIdAuthenticationFilter.setAuthenticationManager(authenticationManager());
        //只有post请求才拦截
        openIdAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
        //openIdAuthenticationFilter.setAuthenticationSuccessHandler(securityAuthenticationSuccessHandler);
        //openIdAuthenticationFilter.setAuthenticationFailureHandler(securityAuthenticationFailureHandler);
       // openIdAuthenticationFilter.setAuthenticationFailureHandler(MyAuthenctiationFailureHandler);
        return openIdAuthenticationFilter;
    }

}


3、添加出错处理

package com.chenclass.xabest.config;


import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component("myAuthenctiationFailureHandler")
public class MyAuthenctiationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
   /* private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ObjectMapper objectMapper;
*/
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
            throws IOException, ServletException {
      //  logger.info("进入认证失败处理类");
//		response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=UTF-8");
        //转发到login
//		request.getRequestDispatcher("/login?error="+exception.getMessage()).forward(request, response);

     //   response.sendRedirect("/login?error="+objectMapper.writeValueAsString(exception.getMessage()));
        String m_strmessage = exception.getMessage();
        if(m_strmessage.equals("jiaoyanmaerror")) {
            response.sendRedirect("/login?codeerror=true");
        }
        else
        {
            response.sendRedirect("/login?error=true");
        }
        return;
    }
}

4、添加KaptchaConfig

 

package com.chenclass.xabest.config;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;

@Component
public class KaptchaConfig {
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
        com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "yes");
        properties.setProperty("kaptcha.border.color", "105,179,90");
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        properties.setProperty("kaptcha.image.width", "110");
        properties.setProperty("kaptcha.image.height", "40");
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        properties.setProperty("kaptcha.session.key", "code");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);

        return defaultKaptcha;
    }
}

5、添加CodeController

package com.chenclass.xabest.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;

@Controller
public class CodeController {
    @Autowired
    private DefaultKaptcha captchaProducer;

    @RequestMapping("/defaultKaptcha")
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        //生成验证码
        String capText = captchaProducer.createText();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        //向客户端写出
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}

6、添加OpenIdAuthenticationFilter

注意:相比于第一篇,修改了出错处理!!! 

package com.chenclass.xabest.filter;

import com.chenclass.xabest.config.MyAuthenctiationFailureHandler;
import com.chenclass.xabest.utils.CodeUtil;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class OpenIdAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    //   @Autowired
    //   private RefactorSysUserService sysUserService;
    public OpenIdAuthenticationFilter() {
      //  AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher("/login", "POST");
     //   this.setRequiresAuthenticationRequestMatcher(requestMatcher);
     //   this.setAuthenticationManager(getAuthenticationManager());
        this.setAuthenticationFailureHandler(new MyAuthenctiationFailureHandler());
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String chen = request.getParameter("username");
        String verify = request.getParameter("vrifyCode");
        int chen1;
        if (!CodeUtil.checkVerifyCode(request)) {
        //出错
        chen1 =2;
          System.out.println("jiaoyanmaerror");
            throw new AuthenticationServiceException("jiaoyanmaerror" );
        } else {
            //正确
            chen1 =3;
        }
       return super.attemptAuthentication(request, response);
    }
}

7、添加工具类CodeUtil

package com.chenclass.xabest.utils;

import javax.servlet.http.HttpServletRequest;

public class CodeUtil {
    /**
     * 将获取到的前端参数转为string类型
     * @param request
     * @param key
     * @return
     */
    public static String getString(HttpServletRequest request, String key) {
        try {
            String result = request.getParameter(key);
            if(result != null) {
                result = result.trim();
            }
            if("".equals(result)) {
                result = null;
            }
            return result;
        }catch(Exception e) {
            return null;
        }
    }
    /**
     * 验证码校验
     * @param request
     * @return
     */
    public static boolean checkVerifyCode(HttpServletRequest request) {
        //获取生成的验证码
        String verifyCodeExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        //获取用户输入的验证码
        String verifyCodeActual = CodeUtil.getString(request, "vrifyCode");
        if(verifyCodeActual == null ||!verifyCodeActual.equals(verifyCodeExpected)) {
            return false;
        }
        return true;
    }
}

 8、在login页面中添加

相比于第1篇,添加了用户名和密码,校验码出错的提示

                <div class="layui-form-item">
                    <span class ="help-block" style="color:red" th:if="${param.error}" th:text="用户或密码错误,请重新输入!"></span>
                    <span class ="help-block" style="color:red" th:if="${param.codeerror}" th:text="校验码错误,请仔细检查!"></span>
                </div>

9、校验成功和失败的处理还没有写,相比于第1篇,在上面的OpenIdAuthenticationFilter中已经补上了

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值