首頁 > 軟體

SpringSecurity新增圖形驗證碼認證實現

2022-08-15 14:03:16

第一步:圖形驗證碼介面

1.使用第三方的驗證碼生成工具Kaptcha

https://github.com/penggle/kaptcha

@Configuration
public class KaptchaImageCodeConfig {
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty(Constants.KAPTCHA_BORDER, "yes");
        properties.setProperty(Constants.KAPTCHA_BORDER_COLOR, "192,192,192");
        properties.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, "110");
        properties.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, "36");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "28");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES, "宋體");
        properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
        // 圖片效果
        properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL,
                "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

2.設定驗證介面

Logger logger = LoggerFactory.getLogger(getClass());
public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
@GetMapping("/code/image")
public void codeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 獲得隨機驗證碼
    String code = defaultKaptcha.createText();
    logger.info("驗證碼:{}",code);
    // 將驗證碼存入session
    request.getSession().setAttribute(SESSION_KEY,code);
    // 繪製驗證碼
    BufferedImage image = defaultKaptcha.createImage(code);
    // 輸出驗證碼
    ServletOutputStream out = response.getOutputStream();
    ImageIO.write(image, "jpg", out);
}

3.模板表單設定

<div class="form-group">
    <label>驗證碼:</label>
    <input type="text" class="form-control" placeholder="驗證碼" name="code">
    <img src="/code/image" th:src="@{/code/image}" onclick="this.src='/code/image?'+Math.random()">
</div>

第二步:設定影象驗證過濾器

1.過濾器

@Component
public class ImageCodeValidateFilter extends OncePerRequestFilter {
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    // 失敗處理器
    @Resource
    public void setMyAuthenticationFailureHandler(MyAuthenticationFailureHandler myAuthenticationFailureHandler) {
        this.myAuthenticationFailureHandler = myAuthenticationFailureHandler;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            if ("/login/form".equals(request.getRequestURI()) &&
                    request.getMethod().equalsIgnoreCase("post")) {
                // 獲取session的驗證碼
                String sessionCode = (String) request.getSession().getAttribute(PageController.SESSION_KEY);
                // 獲取使用者輸入的驗證碼
                String inputCode = request.getParameter("code");
                // 判斷是否正確
                if(sessionCode == null||!sessionCode.equals(inputCode)){
                    throw new ValidateCodeException("驗證碼錯誤");
                }
            }
        }catch (AuthenticationException e){
            myAuthenticationFailureHandler.onAuthenticationFailure(request,response,e);
            //e.printStackTrace();
            return;
        }
        filterChain.doFilter(request, response);
    }
}

異常類

public class ValidateCodeException extends AuthenticationException {
    public ValidateCodeException(String msg) {
        super(msg);
    }
}

注意:一定是繼承AuthenticationException

第三步:將影象驗證過濾器新增到springsecurity過濾器鏈中

1.新增到過濾器鏈中,並設定在使用者認證過濾器(UsernamePasswordAuthenticationFilter)前

@Resource
private ImageCodeValidateFilter imageCodeValidateFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
    // 前後程式碼略
    // 新增圖形驗證碼過濾器鏈
    http.addFilterBefore(imageCodeValidateFilter, UsernamePasswordAuthenticationFilter.class)
}

2.一定不要忘記放行驗證碼介面

// 攔截設定
http
    .authorizeHttpRequests()
    //排除/login
    .antMatchers("/login","/code/image").permitAll();

到此這篇關於SpringSecurity新增圖形驗證碼認證實現的文章就介紹到這了,更多相關SpringSecurity 圖形驗證碼認證內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com