Shiro+JCaptcha 集成验证码

JAVA herman 1595浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

在做用户登录功能时,很多时候都需要验证码支持,验证码的目的是为了防止机器人模拟真实用户登录而恶意访问,如暴力破解用户密码/恶意评论等。目前也有一些验证码比较简单,通过一些OCR工具就可以解析出来;另外还有一些验证码比较复杂(一般通过如扭曲、加线条/噪点等干扰)防止OCR工具识别;但是在中国就是人多,机器干不了的可以交给人来完成,所以在中国就有很多打码平台,人工识别验证码;因此即使比较复杂的如填字、算数等类型的验证码还是能识别的。所以验证码也不是绝对可靠的,目前比较可靠还是手机验证码,但是对于用户来说相对于验证码还是比较麻烦的。
 
对于验证码图片的生成,可以自己通过如Java提供的图像API自己去生成,也可以借助如JCaptcha这种开源Java类库生成验证码图片;JCaptcha提供了常见的如扭曲、加噪点等干扰支持。

配置 JCaptcha 依赖

<dependency>  
    <groupId>com.octo.captcha</groupId>  
    <artifactId>jcaptcha</artifactId>  
    <version>2.0-alpha-1</version>  
</dependency>  
<dependency>  
    <groupId>com.octo.captcha</groupId>  
    <artifactId>jcaptcha-integration-simple-servlet</artifactId>  
    <version>2.0-alpha-1</version>  
    <exclusions>  
        <exclusion>  
            <artifactId>servlet-api</artifactId>  
            <groupId>javax.servlet</groupId>  
        </exclusion>  
    </exclusions>  
</dependency> 

com.octo.captcha.jcaptcha提供了jcaptcha 核心;而jcaptcha-integration-simple-servlet提供了与Servlet集成。

GMailEngine

仿照JCaptcha2.0编写类似GMail验证码的样式

package com.xttblog.shiro18.jcaptcha;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomListColorGenerator;
import com.octo.captcha.component.image.deformation.ImageDeformation;
import com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.FileDictionary;
import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;

import java.awt.*;
import java.awt.image.ImageFilter;

/**
 * from https://code.google.com/p/musicvalley/source/browse/trunk/musicvalley/doc/springSecurity/springSecurityIII/src/main/java/com/spring/security/jcaptcha/GMailEngine.java?spec=svn447&r=447
 * JCaptcha验证码图片生成引擎, 仿照JCaptcha2.0编写类似GMail验证码的样式.
 */
public class GMailEngine extends ListImageCaptchaEngine {

    @Override
    protected void buildInitialFactories() {

        // 图片和字体大小设置
        int minWordLength = 4;
        int maxWordLength = 5;
        int fontSize = 20;
        int imageWidth = 100;
        int imageHeight = 36;

        WordGenerator dictionnaryWords = new ComposeDictionaryWordGenerator(
                new FileDictionary("toddlist"));

        // word2image components
        TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength,
                maxWordLength, new RandomListColorGenerator(new Color[]{
                new Color(23, 170, 27), new Color(220, 34, 11),
                new Color(23, 67, 172)}), new TextDecorator[]{});
        BackgroundGenerator background = new UniColorBackgroundGenerator(
                imageWidth, imageHeight, Color.white);
        FontGenerator font = new RandomFontGenerator(fontSize, fontSize,
                new Font[]{new Font("nyala", Font.BOLD, fontSize),
                        new Font("Bell MT", Font.PLAIN, fontSize),
                        new Font("Credit valley", Font.BOLD, fontSize)});

        ImageDeformation postDef = new ImageDeformationByFilters(
                new ImageFilter[]{});
        ImageDeformation backDef = new ImageDeformationByFilters(
                new ImageFilter[]{});
        ImageDeformation textDef = new ImageDeformationByFilters(
                new ImageFilter[]{});

        WordToImage word2image = new DeformedComposedWordToImage(font,
                background, randomPaster, backDef, textDef, postDef);

        addFactory(new GimpyFactory(dictionnaryWords, word2image));
    }
}

com.xttblog.shiro18.jcaptcha.MyManageableImageCaptchaService提供了判断仓库中是否有相应的验证码存在。

JCaptcha工具类

提供相应的API来验证当前请求输入的验证码是否正确。

public class JCaptcha {  
    public static final MyManageableImageCaptchaService captchaService  
            = new MyManageableImageCaptchaService(new FastHashMapCaptchaStore(),   
                            new GMailEngine(), 180, 100000, 75000);  
    public static boolean validateResponse(  
        HttpServletRequest request, String userCaptchaResponse) {  
        if (request.getSession(false) == null) return false;  
        boolean validated = false;  
        try {  
            String id = request.getSession().getId();  
            validated =   
                captchaService.validateResponseForID(id, userCaptchaResponse)  
                            .booleanValue();  
        } catch (CaptchaServiceException e) {  
            e.printStackTrace();  
        }  
        return validated;  
    }   
    public static boolean hasCaptcha(  
        HttpServletRequest request, String userCaptchaResponse) {  
        if (request.getSession(false) == null) return false;  
        boolean validated = false;  
        try {  
            String id = request.getSession().getId();  
            validated = captchaService.hasCapcha(id, userCaptchaResponse);  
        } catch (CaptchaServiceException e) {  
            e.printStackTrace();  
        }  
        return validated;  
    }  
}
  • validateResponse():验证当前请求输入的验证码否正确;并从CaptchaService中删除已经生成的验证码;
  • hasCaptcha():验证当前请求输入的验证码是否正确;但不从CaptchaService中删除已经生成的验证码(比如Ajax验证时可以使用,防止多次生成验证码);

项目运行效果

Shiro JCaptcha 集成验证码

本文源码下载链接:http://pan.baidu.com/s/1gfn8dyj 密码:w9km

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » Shiro+JCaptcha 集成验证码