开发生成图形验证码的接口:
package com.imooc.security.core.validate.code;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
public class ImageCode {
private BufferedImage image;
private String code;//随机数存到session中
private LocalDateTime expireTime;//有效时间
public ImageCode (BufferedImage image,String code,
int expireIn) {
this.image=image;
this.code=code;
this.expireTime=LocalDateTime.now().plusSeconds(expireIn);
}
public ImageCode (BufferedImage image,String code,
LocalDateTime expireTime) {
this.image=image;
this.code=code;
this.expireTime=expireTime;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public LocalDateTime getExpireTime() {
return expireTime;
}
public void setExpireTime(LocalDateTime expireTime) {
this.expireTime = expireTime;
}
}
package com.imooc.security.core.validate.code;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
@RestController
public class ValidateCodeController {
private static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
@GetMapping("/code/image")
public void createCode(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ImageCode imageCode = createImageCode(request);//code放到sesison 第二步
sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
//将图片写到响应的接口中 第三步
ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
}
private ImageCode createImageCode(HttpServletRequest request) {
//第一步 生成随机验证码 可以去网上搜
int width=67;//宽和高
int height=23;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman",Font.ITALIC,20));
g.setColor(getRandColor(160,200));
for(int i=0;i<155;i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl =random.nextInt(12);
int yl =random.nextInt(12);
g.drawLine(x, y, x+xl, y+yl);
}
String sRand = "";
for (int i = 0; i < 4; i++) {//数字验证码长度
String rand = String.valueOf(random.nextInt(10));
sRand +=rand;
g.setColor(new Color(20 + random.nextInt(110),
20 + random.nextInt(110),20 + random.nextInt(110)));
g.drawString(rand, 13*i+6, 16);
}
g.dispose();
return new ImageCode(image,sRand,60);//有效期60秒
}
/**
* 生成随机背景条纹
*/
private Color getRandColor(int fc,int bc) {
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r,g,b);
}
}
package com.imooc.security.browser;
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.web.builders.HttpSecurity;
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.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import com.imooc.security.browser.authentication.ImoocAuthenticationSuccessHandler;
import com.imooc.security.core.properties.SecurityProperties;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private SecurityProperties securityProperties;
//让系统使用我们自定义 而不是系统默认的配置
@Autowired
private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler imoocAuthenticationFailureHandler;
@Bean
public PasswordEncoder passwordEncoder() {
//这里如果是自己编写的加密 则调用自己的类 方法有编码和解码验证方法
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//认证
.loginPage("/authentication/require")//设置登录页面
.loginProcessingUrl("/authentication/form")//遇到该请求则进行user password认证
.successHandler(imoocAuthenticationSuccessHandler)//成功后 使用我们自己的处理器处理
.failureHandler(imoocAuthenticationFailureHandler)//设置失败处理器
// http.httpBasic()
.and()
.authorizeRequests()//授权
//当访问这个路径的时候不需要身份认证 除了它其他的是需要身份认证
.antMatchers("/authentication/require"
,securityProperties.getBrowsers().getLoginPage()
,"/code/image").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="brilliance.znjt.business.workassess.dao.WorkAssessMapper">
<update id="gwsdsettingDay">
UPDATE T_GWSD_SETTING T
SET T.KSSJ = #{kssj},
T.JSSJ = #{jssj}
WHERE T.NAME = '白班'
</update>
<update id="gwsdsettingNight">
UPDATE T_GWSD_SETTING T
SET T.KSSJ = #{kssj},
T.JSSJ = #{jssj}
WHERE T.NAME = '夜班'
</update>
<insert id="insertWfcf" parameterType="brilliance.znjt.business.workassess.entity.Wfcf">
INSERT INTO T_WFXW_SCORE
<trim prefix="(" suffix=")" suffixOverrides=",">
JDBH,
<if test="jdmc != null and jdmc != ''">
JDMC,
</if>
<if test="wfdm != null and wfdm != ''">
WFDM,
</if>
<if test="ysjd != 0">
YSJD,
</if>
<if test="jdqz != 0">
JDQZ,
</if>
<if test="sjjd != 0">
SJJD,
</if>
<!-- <if test="jdfl != null and jdfl != ''">
JDFL,
</if> -->
<if test="jdsm != null and jdsm != ''">
JDSM,
</if>
<if test="sjly != null and sjly != ''">
SJLY,
</if>
<if test="lrr != null and lrr !=''">
LRR,
</if>
LRSJ,
<if test="gxr != null and gxr !=''">
GXR,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
ZNJTPOSTMAN.FPOSTMAN_NEXTVAL('SEQ_T_WFXW_SCORE_CODE'),
<if test="jdmc != null and jdmc != ''">
#{jdmc,jdbcType=VARCHAR},
</if>
<if test="wfdm != null and wfdm != ''">
#{wfdm,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
#{sjjd,jdbcType=INTEGER},
</if>
<!-- <if test="jdfl != null and jdfl != ''">
#{jdfl,jdbcType=VARCHAR},
</if> -->
<if test="jdsm != null and jdsm != ''">
#{jdsm,jdbcType=VARCHAR},
</if>
<if test="sjly != null and sjly != ''">
#{sjly,jdbcType=VARCHAR},
</if>
<if test="lrr != null and lrr !=''">
#{lrr,jdbcType=VARCHAR},
</if>
SYSDATE,
<if test="gxr != null and gxr !=''">
#{gxr,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<delete id="removeByWfflAndWflx" parameterType="java.lang.String">
DELETE T_WFXW_FL T
WHERE T.WFLX = #{wffl,jdbcType=VARCHAR}
AND T.WFXW = #{wfxw,jdbcType=VARCHAR}
</delete>
<insert id="addWfflAndXw" parameterType="brilliance.znjt.business.workassess.entity.Wffl">
INSERT INTO T_WFXW_FL
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="wflx != null and wflx != ''">
WFLX,
</if>
<if test="wfxw != null and wfxw != ''">
WFXW,
</if>
<if test="sfxs != null and sfxs != ''">
SFXS,
</if>
<if test="px != null and px != ''">
PX,
</if>
<if test="lrr != null and lrr != ''">
LRR,
</if>
LRSJ
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="wflx != null and wflx != ''">
#{wflx,jdbcType=VARCHAR},
</if>
<if test="wfxw != null and wfxw != ''">
#{wfxw,jdbcType=VARCHAR},
</if>
<if test="sfxs != null and sfxs != ''">
#{sfxs,jdbcType=INTEGER},
</if>
<if test="px != null and px != ''">
#{px,jdbcType=INTEGER},
</if>
<if test="lrr != null and lrr != ''">
#{lrr,jdbcType=VARCHAR},
</if>
sysdate
</trim>
</insert>
<update id="updateWfflAndXw" parameterType="brilliance.znjt.business.workassess.entity.Wffl">
UPDATE T_WFXW_FL
<set>
<if test="wflx != null and wflx != ''">
WFLX = #{wflx,jdbcType=VARCHAR},
</if>
<if test="wfxw != null and wfxw != ''">
WFXW = #{wfxw,jdbcType=VARCHAR},
</if>
<if test="sfxs != null and sfxs != ''">
SFXS = #{sfxs,jdbcType=VARCHAR},
</if>
<if test="px != null and px != ''">
PX = #{px,jdbcType=VARCHAR},
</if>
<if test="lrr != null and lrr != ''">
LRR = #{lrr,jdbcType=VARCHAR},
</if>
</set>
WHERE WFLX = #{originalwflx,jdbcType=VARCHAR}
AND WFXW = #{originalwfxw,jdbcType=VARCHAR}
</update>
<update id="updateWfcf" parameterType="brilliance.znjt.business.workassess.entity.Wfcf">
UPDATE T_WFXW_SCORE
<set>
<if test="jdmc != null and jdmc != ''">
JDMC=#{jdmc,jdbcType=VARCHAR},
</if>
<if test="wfdm != null and wfdm != ''">
WFDM=#{wfdm,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
YSJD=#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
JDQZ=#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
SJJD=#{sjjd,jdbcType=INTEGER},
</if>
<!-- <if test="jdfl != null and jdfl != ''">
JDFL,
</if> -->
<if test="jdsm != null and jdsm != ''">
JDSM= #{jdsm,jdbcType=VARCHAR},
</if>
<if test="sjly != null and sjly != ''">
SJLY=#{sjly,jdbcType=VARCHAR},
</if>
<!-- <if test="lrr != null and lrr !=''">
LRR=#{lrr,jdbcType=VARCHAR},,
</if> -->
<if test="gxr != null and gxr !=''">
GXR=#{gxr,jdbcType=VARCHAR},
</if>
GXSJ=SYSDATE,
</set>
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
</update>
<delete id="deleteWfcf" parameterType="java.lang.String">
DELETE FROM T_WFXW_SCORE
WHERE JDBH
IN
<foreach item="item" collection="list" open="(" separator="," close=")">
#{item,jdbcType=VARCHAR}
</foreach>
</delete>
<insert id="insertJcj" parameterType="brilliance.znjt.business.workassess.entity.Jcj">
INSERT INTO T_JCJ_SCORE
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="jdbh != null and jdbh != ''">
JDBH,
</if>
<if test="jdmc != null and jdmc != ''">
JDMC,
</if>
<if test="ysjd != 0">
YSJD,
</if>
<if test="jdqz != 0">
JDQZ,
</if>
<if test="sjjd != 0">
SJJD,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="jdbh != null and jdbh != ''">
#{jdbh,jdbcType=VARCHAR},
</if>
<if test="jdmc != null and jdmc != ''">
#{jdmc,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
#{sjjd,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateJcj" parameterType="brilliance.znjt.business.workassess.entity.Jcj">
UPDATE T_JCJ_SCORE
<set>
<if test="jdmc != null and jdmc != ''">
JDMC=#{jdmc,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
YSJD=#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
JDQZ=#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
SJJD=#{sjjd,jdbcType=INTEGER},
</if>
</set>
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
</update>
<delete id="deleteJcj" parameterType="java.lang.String">
DELETE FROM T_JCJ_SCORE
WHERE JDBH
IN
<foreach item="item" collection="list" open="(" separator="," close=")">
#{item,jdbcType=VARCHAR}
</foreach>
</delete>
<select id="isExists" parameterType="java.lang.String" resultType="java.lang.Integer">
SELECT
COUNT(1)
FROM T_JCJ_SCORE J
WHERE J.JDBH = #{jdbh,jdbcType=VARCHAR}
</select>
<insert id="insertQw" parameterType="brilliance.znjt.business.workassess.entity.Jcj">
INSERT INTO T_QW_SCORE
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="jdbh != null and jdbh != ''">
JDBH,
</if>
<if test="jdmc != null and jdmc != ''">
JDMC,
</if>
<if test="ysjd != 0">
YSJD,
</if>
<if test="jdqz != 0">
JDQZ,
</if>
<if test="sjjd != 0">
SJJD,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="jdbh != null and jdbh != ''">
#{jdbh,jdbcType=VARCHAR},
</if>
<if test="jdmc != null and jdmc != ''">
#{jdmc,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
#{sjjd,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateQw" parameterType="brilliance.znjt.business.workassess.entity.Jcj">
UPDATE T_QW_SCORE
<set>
<if test="jdmc != null and jdmc != ''">
JDMC=#{jdmc,jdbcType=VARCHAR},
</if>
<if test="ysjd != 0">
YSJD=#{ysjd,jdbcType=INTEGER},
</if>
<if test="jdqz != 0">
JDQZ=#{jdqz,jdbcType=INTEGER},
</if>
<if test="sjjd != 0">
SJJD=#{sjjd,jdbcType=INTEGER},
</if>
</set>
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
</update>
<delete id="deleteQw" parameterType="java.lang.String">
DELETE FROM T_QW_SCORE
WHERE JDBH
IN
<foreach item="item" collection="list" open="(" separator="," close=")">
#{item,jdbcType=VARCHAR}
</foreach>
</delete>
</mapper>
访问html结果:
接下来进行验证配置:
package com.imooc.security.browser;
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.web.builders.HttpSecurity;
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.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.imooc.security.browser.authentication.ImoocAuthenticationSuccessHandler;
import com.imooc.security.core.properties.SecurityProperties;
import com.imooc.security.core.validate.code.ValidateCodeFilter;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private SecurityProperties securityProperties;
//让系统使用我们自定义 而不是系统默认的配置
@Autowired
private AuthenticationSuccessHandler imoocAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler imoocAuthenticationFailureHandler;
@Bean
public PasswordEncoder passwordEncoder() {
//这里如果是自己编写的加密 则调用自己的类 方法有编码和解码验证方法
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler);
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
.formLogin()//认证
.loginPage("/authentication/require")//设置登录页面
.loginProcessingUrl("/authentication/form")//遇到该请求则进行user password认证
.successHandler(imoocAuthenticationSuccessHandler)//成功后 使用我们自己的处理器处理
.failureHandler(imoocAuthenticationFailureHandler)//设置失败处理器
// http.httpBasic()
.and()
.authorizeRequests()//授权
//当访问这个路径的时候不需要身份认证 除了它其他的是需要身份认证
.antMatchers("/authentication/require"
,securityProperties.getBrowsers().getLoginPage()
,"/code/image").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
/**
*
*/
package com.imooc.security.browser.authentication;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.security.browser.support.SimpleResponse;
import com.imooc.security.core.properties.LoginType;
import com.imooc.security.core.properties.SecurityProperties;
/**
* @author 35-pxiaodong
*
*/
@Component("imoocAuthenticatinFailureHandler")
public class ImoocAuthenticatinFailureHandler
extends SimpleUrlAuthenticationFailureHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;//启动的时候springmvc会注册一个mapper
@Autowired
private SecurityProperties securityProperties;
/* (non-Javadoc)
* @see org.springframework.security.web.authentication.AuthenticationFailureHandler#onAuthenticationFailure(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.AuthenticationException)
*/
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
logger.info("登录失败");
logger.info("loginType是:"+securityProperties.getBrowsers().getLoginType());
//返回json
if (LoginType.JSON.equals(securityProperties.getBrowsers().getLoginType())) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());//设置错误500状态
response.setContentType("application/json,charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(new SimpleResponse(exception.getMessage())));
}else {//返回页面
super.onAuthenticationFailure(request, response, exception);;//父类的方法就是跳转
}
}
}
package com.imooc.security.core.properties;
public class BrowserProperties {
//设定默认值如果没有指定loginPage则访问该页面
private String loginPage = "/imooc-signIn.html";
private LoginType loginType=LoginType.JSON;//默认返回json
// private LoginType loginType=LoginType.REDIRECT;
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
public LoginType getLoginType() {
return loginType;
}
public void setLoginType(LoginType loginType) {
this.loginType = loginType;
}
}
package com.imooc.security.core.validate.code;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
public class ImageCode {
private BufferedImage image;
private String code;//随机数存到session中
private LocalDateTime expireTime;//有效时间
public ImageCode (BufferedImage image,String code,
int expireIn) {
this.image=image;
this.code=code;
this.expireTime=LocalDateTime.now().plusSeconds(expireIn);
}
public ImageCode (BufferedImage image,String code,
LocalDateTime expireTime) {
this.image=image;
this.code=code;
this.expireTime=expireTime;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public LocalDateTime getExpireTime() {
return expireTime;
}
public void setExpireTime(LocalDateTime expireTime) {
this.expireTime = expireTime;
}
public boolean isExpried() {
return LocalDateTime.now().isAfter(expireTime);
}
}
package com.imooc.security.core.validate.code;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
@RestController
public class ValidateCodeController {
public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
@GetMapping("/code/image")
public void createCode(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ImageCode imageCode = createImageCode(request);//code放到sesison 第二步
sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
//将图片写到响应的接口中 第三步
ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
}
private ImageCode createImageCode(HttpServletRequest request) {
//第一步 生成随机验证码 可以去网上搜
int width=67;//宽和高
int height=23;
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman",Font.ITALIC,20));
g.setColor(getRandColor(160,200));
for(int i=0;i<155;i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl =random.nextInt(12);
int yl =random.nextInt(12);
g.drawLine(x, y, x+xl, y+yl);
}
String sRand = "";
for (int i = 0; i < 4; i++) {//数字验证码长度
String rand = String.valueOf(random.nextInt(10));
sRand +=rand;
g.setColor(new Color(20 + random.nextInt(110),
20 + random.nextInt(110),20 + random.nextInt(110)));
g.drawString(rand, 13*i+6, 16);
}
g.dispose();
return new ImageCode(image,sRand,60);//有效期60秒
}
/**
* 生成随机背景条纹
*/
private Color getRandColor(int fc,int bc) {
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r,g,b);
}
}
package com.imooc.security.core.validate.code;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;
public class ValidateCodeFilter extends OncePerRequestFilter{
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//主干逻辑
if (StringUtils.equals("/authentication/form", request.getRequestURI())
&& StringUtils.equalsIgnoreCase(request.getMethod(),"post")) {
try {
//校验逻辑
validate(new ServletWebRequest(request));
} catch (ValidateCodeException e) {
authenticationFailureHandler.onAuthenticationFailure(request, response, e);
return;
}
}
filterChain.doFilter(request, response);
}
//校验逻辑
private void validate(ServletWebRequest request) throws ServletRequestBindingException {
ImageCode codeInSession = (ImageCode)sessionStrategy.getAttribute(request,
ValidateCodeController.SESSION_KEY);
String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "imageCode");
if (StringUtils.isBlank(codeInRequest)) {
throw new ValidateCodeException("验证码的值不能为空,the code must be not null");
}
if (codeInSession == null) {
throw new ValidateCodeException("验证码不存在");
}
if (codeInSession.isExpried()) {
sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
throw new ValidateCodeException("验证码已过期");
}
if (!StringUtils.equals(codeInSession.getCode(), codeInRequest)) {
throw new ValidateCodeException("验证码不匹配");
}
sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
}
public AuthenticationFailureHandler getAuthenticationFailureHandler() {
return authenticationFailureHandler;
}
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
this.authenticationFailureHandler = authenticationFailureHandler;
}
public SessionStrategy getSessionStrategy() {
return sessionStrategy;
}
public void setSessionStrategy(SessionStrategy sessionStrategy) {
this.sessionStrategy = sessionStrategy;
}
}
启动访问测试:
再试个正确的验证码
数据拿到了,嘿嘿嘿,
到这里我都感觉代码很乱了,赶紧把源码保存一下。
这里:https://download.csdn.net/download/qq_36421955/10758578