02.实现图形验证码

实现图形验证码

使用过滤器实现图形验证码

使用kaptcha验证码

       <!--验证码组件-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>
/**
 * 自定义身份验证失败处理程序
 */
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"error_code\":\"401\",\"name\":\""+e.getClass()+"\",\"message\":\""+e.getMessage()+"\"}");
    }
}
public class VerificationCodeException extends AuthenticationException {
    public VerificationCodeException(){
        super("验证码校验失败");
    }
}
/**
 * 验证码过滤器
 * OncePerRequestFilter 确保一次请求只会通过一次该过滤器
 * 核对session中保存的验证码与用户提交的验证码是否一致
 * // /auth/form 登录请求才校验验证码
 *  {@link WebSecurityConfig}
 */
public class VerificationCodeFilter extends OncePerRequestFilter  {
    private AuthenticationFailureHandler handler = new MyAuthenticationFailureHandler();
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if ("/auth/form".equals(request.getRequestURI())){
            try {
                verificationCode(request);
                filterChain.doFilter(request,response);
            }catch (VerificationCodeException e){
                handler.onAuthenticationFailure(request,response,e);
            }
        }else {
            filterChain.doFilter(request,response);
        }
    }

    public void verificationCode(HttpServletRequest request) throws VerificationCodeException {
        String requestCode = request.getParameter("captcha");
        HttpSession session = request.getSession();
        String saveCode = (String) session.getAttribute("captcha");
        if (!StringUtils.isEmpty(saveCode)){
            //随手清除验证码
            session.removeAttribute("captcha");
        }
        //校验不通过,抛出异常
        if (StringUtils.isEmpty(requestCode)||StringUtils.isEmpty(saveCode)||!requestCode.equals(saveCode)){
            throw new VerificationCodeException();
        }
    }
}
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Bean
    public AuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService());
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/api/**").hasRole("ADMIN")
                .antMatchers("/user/api/**").hasRole("USER")
                .antMatchers("/app/api/**", "/captcha","/captchaLogin.html").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/captchaLogin.html")
                .loginProcessingUrl("/auth/form")
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=UTF-8");
                        httpServletResponse.getWriter().write("{\"error_code\":\"0\",\"message\":\"欢迎登陆\"}");
                    }
                })
                .failureHandler(new MyAuthenticationFailureHandler())
//                .and().sessionManagement().maximumSessions(1)
//                .and().and().csrf().disable();
                .and().csrf().disable();
        http.addFilterBefore(new VerificationCodeFilter(), UsernamePasswordAuthenticationFilter.class);
    }
    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user").password(new BCryptPasswordEncoder().encode("123")).roles("USER").build());
        manager.createUser(User.withUsername("admin").password(new BCryptPasswordEncoder().encode("123")).roles("ADMIN").build());
        return manager;
    }
}

测试

@Controller
@SpringBootApplication(scanBasePackages = "com.security.config.captchaConfig")
public class Captchabootstrap {
    public static void main(String[] args) {
        SpringApplication.run(Captchabootstrap.class);
    }
    @Autowired
    private Producer captchaProducer;
    @Bean
    public Producer captcha(){
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width","150");
        properties.setProperty("kaptcha.image.height","150");
        //字符集
        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;
    }

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("image/jpeg");
        String capText = captchaProducer.createText();
        request.getSession().setAttribute("captcha",capText);
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi,"jpg",out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }

    @GetMapping("/index")
    @ResponseBody
    public String index(){
        return "index";
    }
    @GetMapping("/admin/api")
    public String admin(){
        return "hello,admin";
    }
    @GetMapping("/user/api")
    public String user(){
        return "hello,user";
    }
    @GetMapping("/app/api")
    public String app(){
        return "hello,app";
    }
}
<body>
<h1>login</h1>
<div>
    username:<input id="username" type="text" name="username"><hr>
    password:<input id="password" type="password" name="password"><hr>
    <div style="display:flex;">
        <input type="text" name="captcha" id="captcha">
        <img src="/captcha" height="50px" width="150px" style="" alt="">
    </div>
    <button onclick="submit()">submit</button>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
        function submit(){
            var username = $('#username').val();
            var password = $('#password').val();
            var captcha = $('#captcha').val();
            $.post("/auth/form",{username:username,password:password,captcha:captcha},function (res) {
                if (res.error_code=='0'){
                    window.location.href="http://localhost:8080/index"
                }
            })
        }
    </script>
</body>

使用自定义认证实现图形验证码

public class MyWebAuthenticationDetails extends WebAuthenticationDetails {
    private boolean imageCodeIsRight;
    public boolean getImageCodeIsRight(){
        return imageCodeIsRight;
    }

    public MyWebAuthenticationDetails(HttpServletRequest request) {
        super(request);
        String imageCode = request.getParameter("captcha");
        HttpSession session = request.getSession();
        String saveImageCode = (String)session.getAttribute("captcha");
        if (!StringUtils.isEmpty(saveImageCode)){
            session.removeAttribute("captcha");
            if (!StringUtils.isEmpty(imageCode)&&imageCode.equals(saveImageCode)){
                this.imageCodeIsRight = true;
            }
        }
    }
}
    
@Component
public class MyWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {

    @Override
    public WebAuthenticationDetails buildDetails(HttpServletRequest request) {
        return new MyWebAuthenticationDetails(request);
    }
}
public class MyAuthenticationProvider extends DaoAuthenticationProvider {
    public MyAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        setUserDetailsService(userDetailsService);
        setPasswordEncoder(passwordEncoder);
    }

    /**
     * 其他身份验证检查
     * @param userDetails
     * @param authentication
     * @throws AuthenticationException
     */
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        MyWebAuthenticationDetails details = (MyWebAuthenticationDetails) authentication.getDetails();
        if (!details.getImageCodeIsRight()){
            throw new VerificationCodeException();
        }
        super.additionalAuthenticationChecks(userDetails, authentication);
    }
}
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> myWebAuthenticationDetailsAuthenticationDetailsSource;
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Bean
    public MyAuthenticationProvider myAuthenticationProvider(){
        return new MyAuthenticationProvider(userDetailsService(),passwordEncoder());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(myAuthenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/api/**").hasRole("ADMIN")
                .antMatchers("/user/api/**").hasRole("USER")
                .antMatchers("/app/api/**", "/captcha","/captchaLogin.html").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .authenticationDetailsSource(myWebAuthenticationDetailsAuthenticationDetailsSource)
                .loginPage("/captchaLogin.html")
                .loginProcessingUrl("/auth/form")
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setContentType("application/json;charset=UTF-8");
                        httpServletResponse.getWriter().write("{\"error_code\":\"0\",\"message\":\"欢迎登陆\"}");
                    }
                })
                .failureHandler(new MyAuthenticationFailureHandler())
                .and().csrf().disable();
    }
    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user").password(new BCryptPasswordEncoder().encode("123")).roles("USER").build());
        manager.createUser(User.withUsername("admin").password(new BCryptPasswordEncoder().encode("123")).roles("ADMIN").build());
        return manager;
    }
}

原文地址:https://www.cnblogs.com/fly-book/p/12230759.html

时间: 2024-10-18 10:26:05

02.实现图形验证码的相关文章

图形验证码如何解决集群中使用问题

刚才写了一篇文章关于图形验证码的,感觉没有考虑集群情况.其实集群无非加一个集群缓存 将session换成redis或者memcatch. 今天记录一下 使用 redis做集群图形验证码的相关方案. 基于文章: http://www.cnblogs.com/owenma/p/7375540.html 添加redis: 在获取和存储的地方使用的是redis封装好的cacheManager. @RequestMapping(value = "/getKaptchaImage", method

图形验证码实现方案(解决短信轰炸问题)

最近收到leader的一个邮件说我们的项目有短信轰炸风险.顿时让一个做技术开发的人为之一颤.今天给大家介绍一个解决这个问题的使用工具. 就是谷歌的 kaptcha 进行验证码生成和校验.闲话少说直接上代码. 1. 首先下载一个工具包 <dependency> <groupId>com.github.axet</groupId> <artifactId>kaptcha</artifactId> <version>0.0.9</ve

生成图形验证码

介绍生成两种类型的图形验证码: 1.普通的随机字符串;  2.随机运算表达式 图形验证码类: /// <summary> /// 图形验证码类 /// </summary> public class PicCaptcha { #region Constructed Methods /// <summary> /// 默认构造方法 /// </summary> public PicCaptcha() { } /// <summary> ///构造方

12306 图形验证码分析

验证码是一个非常有意思的问题,它的目的是区分输入者是人还是机器,这个问题本质上是一个图灵测试(推荐电影<模仿游戏>),验证码即是一种简单高效的验证方法,由CMU的教授于2000年左右创造,后来此牛人又将零星的验证码收集起来,转化为巨大的生产力,成功将上千万篇纸质文章数字化,目前Google还用其识别门牌号,路牌等(一个神人创造了验证码,又让验证码做出了巨大贡献).12306昨天改用了图形验证码,而事实上,图形验证码已经不是新鲜事了,早在几个月钱,Google就换成了图形验证(谷歌让验证码更简单

图形验证码

新建一个.cs文件用来写生成图形验证码的方法,返回一个MemoryStream的参数.在Default.aspx中接收输出就可以了. 1.下面是.cs的代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; us

Servlet实现图形验证码

1. 开发环境 |-- tomcat7 |-- eclipse |-- jdk1.7 2. 项目结构 |-- demo |-- src |-- asia.hchx.filter |-- CharacterFilter |-- LoginFilter |-- asia.hchx.servlet |-- LoginServlet |-- VerifyImage |-- WebContent |-- index.jsp |-- login.jsp 3. 测试步骤 |-- 创建web项目 |-- 配置开

Python验证码识别--利用pytesser识别简单图形验证码

一.探讨 识别图形验证码可以说是做爬虫的必修课,涉及到计算机图形学,机器学习,机器视觉,人工智能等等高深领域…… 简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形.以及利用计算机进行图形的计算.处理和显示的相关原理与算法.图形通常由点.线.面.体等几何元素和灰度.色彩.线型.线宽等非几何属性组成.计算机涉及到的几何图形处理一般有 2维到n维图形处理,边界区分,面积计算,体积计算,扭曲变形校正.对于颜色则有色彩空间的计算与转换,图形上色,阴影,色差处理等等. 在破解验证码中需要用

python爬虫中图形验证码的处理

使用python爬虫自动登录时,遇到需要输入图形验证码的情况,一个比较简单的处理方法是使用打码平台识别验证码. 使用过两个打码平台,打码兔和若快,若快的价格更便宜,识别率相当.若快需要注册两个帐号:开发者帐号与用户帐号,用户帐号用于发送识别请求,开发者帐号可以注册软件id,并于识别请求进行绑定,可以参与识别收入的分成返现. 获取图形验证码目前发现的有两种方式: 0x01 在抓包中可以直接获得图片:发送get请求可以直接获取图片(png或jpg格式),这种情况可以使用request.get()返回

关于杭州绿城项目短信验证码前加图形验证码,我说用这种方式的都是蠢材

日前,某外包公司帮杭州绿城做了屋牛项目,改项目的短信平台遭到恶意大规模的请求,向运营商购买的短信很快耗尽.该团队想了方法即在短信验证码前加图形验证码. 分析一下,黑客模拟发起短信验证码的请求,他只能根据他获得得到的数据进行模拟,这里指一般的黑客攻击,且只针对此具体问题.对http熟悉的,都知道4个域,application.request.response.session.如果我们在session(或者HttpRuntime.Cache)里放一个token,每次请求比对该token,再辅以每个号