security实现验证码andRemember-Me(上)

简介: security实现验证码andRemember-Me(上)

实现验证码



导入依赖


<!--验证码相关的依赖-->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>


定义验证码配置类


package Rememberme.config;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
 * 验证码相关配置
 */
@Configuration
public class KaptchaConfig {
    @Bean
    public Producer kaptcha() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "150");
        properties.setProperty("kaptcha.image.height", "50");
        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;
    }
}


定义验证码的拦截器


//自定义验证码Filter
public class kaptchaFilter extends UsernamePasswordAuthenticationFilter {
}


自定义拦截器配置类,实现UsernamePasswordAuthenticationFilter

然后设置默认的拦截器

//类似源码,定义默认值
public static final String KAPTCHA_KEY = "kaptcha";//默认值
private String kaptcha = KAPTCHA_KEY;
实现拦截器的验证方法attemptAuthentication


@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    //1. 验证请求判断是否为post
    if (!request.getMethod().equalsIgnoreCase("post")) {
        throw new KaptchaNotMatchException("请求异常" + request.getMethod());
    }
    //2.获取验证码
    String kaptcha = request.getParameter(getKaptcha());
    String sessionKaptcha = (String) request.getSession().getAttribute("kaptcha");
    if (!ObjectUtils.isEmpty(kaptcha)
        && !ObjectUtils.isEmpty(sessionKaptcha)
        && kaptcha.equalsIgnoreCase(sessionKaptcha)) {
        //3. 返回自定义的组件
        return super.attemptAuthentication(request, response);
    }
    throw new KaptchaNotMatchException("验证码异常!");
}


自定义拦截器配置


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public kaptchaFilter KaptchaFilter() throws Exception {
        kaptchaFilter filter = new kaptchaFilter();
        //指定处理登录
        filter.setFilterProcessesUrl("/doLogin");
        //setUsername、password....
        //指定接受拦截器的请求参数名
        filter.setKaptcha("kaptcha");
        //自定义拦截器的认证管理器
        filter.setAuthenticationManager(authenticationManagerBean());
        //指定认证成功或者失败的请求
        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("msg", "登录成功!");
            result.put("status", "200");
            result.put("用户信息", (User) authentication.getPrincipal());
            response.setContentType("application/json;charset=UTF-8");
            String s = new ObjectMapper().writeValueAsString(result);
            response.getWriter().println(s);
        });
        filter.setAuthenticationFailureHandler((request, response, exception) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("msg", "登录失败!!");
            result.put("status", "400");
            result.put("错误信息", exception.getMessage());
            response.setContentType("application/json;charset=UTF-8");
            String s = new ObjectMapper().writeValueAsString(result);
            response.getWriter().println(s);
        });
        return filter;
    }
}


注意点


//指定接受拦截器的请求参数名
filter.setKaptcha("kaptcha");
//自定义拦截器的认证管理器
filter.setAuthenticationManager(authenticationManagerBean());


将自定义的拦截器交给容器


用来将自定义AuthenticationManager在工厂中进行暴露,可以在任何位置注入

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //用来将自定义AuthenticationManager在工厂中进行暴露,可以在任何位置注入
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    public kaptchaFilter KaptchaFilter() throws Exception {
        kaptchaFilter filter = new kaptchaFilter();
        //指定处理登录
        filter.setFilterProcessesUrl("/doLogin");
        //setUsername、password....
        //指定接受拦截器的请求参数名
        filter.setKaptcha("kaptcha");
        //自定义拦截器的认证管理器
        filter.setAuthenticationManager(authenticationManagerBean());
        //指定认证成功或者失败的请求
        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("msg", "登录成功!");
            result.put("status", "200");
            result.put("用户信息", (User) authentication.getPrincipal());
            response.setContentType("application/json;charset=UTF-8");
            String s = new ObjectMapper().writeValueAsString(result);
            response.getWriter().println(s);
        });
        filter.setAuthenticationFailureHandler((request, response, exception) -> {
            Map<String, Object> result = new HashMap<>();
            result.put("msg", "登录失败!!");
            result.put("status", "400");
            result.put("错误信息", exception.getMessage());
            response.setContentType("application/json;charset=UTF-8");
            String s = new ObjectMapper().writeValueAsString(result);
            response.getWriter().println(s);
        });
        return filter;
    }
}


替换自己的拦截器



//替换默认拦截器
        http.addFilterAt(KaptchaFilter(), UsernamePasswordAuthenticationFilter.class);


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers("/index").permitAll()
                .mvcMatchers("/loginPages").permitAll()
                .mvcMatchers("/vc.jpg").permitAll()     //放行验证码的请求
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/loginPages")
//                .loginProcessingUrl("/doLogin")
//                .defaultSuccessUrl("/index")
//                .failureUrl("/loginPage")
//                .and()
//                .logout()
//                .logoutSuccessUrl("/index")
                .and()
                .csrf().disable();
  //替换默认拦截器
        http.addFilterAt(KaptchaFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}


controller配置验证码拦截器发送的请求


@RequestMapping("/vc.jpg")
public void Kaptcha(HttpServletResponse response, HttpSession session) throws IOException {
    response.setContentType("image/png");
    String text = producer.createText();
    session.setAttribute("kaptcha", text);
    BufferedImage image = producer.createImage(text);
    ServletOutputStream stream = response.getOutputStream();
    ImageIO.write(image, "jpg", stream);
}


前端实现请求接口


验证码: <input name="kaptcha" type="text"/> <img alt="" th:src="@{/vc.jpg}"><br>


目录
相关文章
|
编解码 前端开发 开发者
【Web 前端】CSS常用尺寸单位有哪些?应用场景?
【4月更文挑战第22天】【Web 前端】CSS常用尺寸单位有哪些?应用场景?
TypeScript-声明合并
TypeScript-声明合并
141 0
|
2天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
12天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
6天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
483 201