Commit 5d3e7966 by Java-曹文达

添加验证码

parent 0fd01c4a
......@@ -70,6 +70,13 @@
</exclusions>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>com.github.bingoohuang</groupId>
<artifactId>patchca</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
......
package com.bbd.bpm.config;
import org.springframework.security.core.AuthenticationException;
/**
* @ClassName ValidateCodeException
* @Description TODO
* @Author 啦啦啦
* @Date 2019/4/16 11:04
* @Version 1.0
**/
public class ValidateCodeException extends AuthenticationException {
public ValidateCodeException(String msg) {
super(msg);
}
}
......@@ -4,6 +4,7 @@ package com.bbd.bpm.config;
import com.bbd.bpm.domain.User;
import com.bbd.bpm.repository.UserRepository;
import com.bbd.bpm.util.VerifycodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -14,6 +15,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
......@@ -37,7 +39,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception { //配置策略
http.csrf().disable();
http.authorizeRequests().
antMatchers("/v2/api-docs","/swagger-resources/**","/webjars/**","/images/**").permitAll().anyRequest().authenticated().
antMatchers("/v2/api-docs","/swagger-resources/**","/webjars/**","/images/**","/loadverify").permitAll().anyRequest().authenticated().
and().headers().frameOptions().disable().
and().formLogin().loginPage("/login").permitAll().successHandler(loginSuccessHandler()).
and().logout().permitAll().invalidateHttpSession(true).
......@@ -80,12 +82,25 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
return new SavedRequestAwareAuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//获取验证码
String msgCode = request.getParameter("msgCode");
//验证码是否正确
String seCode = VerifycodeUtils.getVerifyCodeBySession(request);
if (msgCode == null || !msgCode.equalsIgnoreCase(seCode)) {
throw new ValidateCodeException ("seCode " + seCode + "验证码不正确");
}
User userDetails = (User) authentication.getPrincipal();
logger.info("USER : " + userDetails.getUsername() + " LOGIN SUCCESS ! ");
super.onAuthenticationSuccess(request, response, authentication);
}
};
}
@Bean
@Override
public UserDetailsService userDetailsService() { //用户登录实现
......
package com.bbd.bpm.controller.user;
import com.bbd.bpm.domain.User;
import com.bbd.bpm.util.VerifycodeUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
......@@ -13,6 +14,7 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
/**
......@@ -43,4 +45,20 @@ public class LoginController {
public HttpServletRequest getRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
/**
* @描述:加载验证码
* @param:
* @return:
* @作者: cwd
* @创建时间:2017/6/1 10:20
*/
@RequestMapping(value = "/loadverify", method = RequestMethod.GET)
public void loadVerifyCode(HttpServletRequest request, HttpServletResponse response) {
VerifycodeUtils.makeVerifyImageByNum(request, response, 4);
}
}
\ No newline at end of file
package com.bbd.bpm.util;
import com.github.bingoohuang.patchca.background.SingleColorBackgroundFactory;
import com.github.bingoohuang.patchca.color.SingleColorFactory;
import com.github.bingoohuang.patchca.custom.ConfigurableCaptchaService;
import com.github.bingoohuang.patchca.filter.predefined.CurvesRippleFilterFactory;
import com.github.bingoohuang.patchca.utils.encoder.EncoderHelper;
import com.github.bingoohuang.patchca.word.RandomWordFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* @Copyright 2018 BaiBangDa All rights reserved.
*/
public class VerifycodeUtils {
private static final Logger logger = LoggerFactory.getLogger(VerifycodeUtils.class);
/**
* 使用最新的验证码生成器
*
* @param request
* @param response
*/
public static void makeVerifyImage(HttpServletRequest request, HttpServletResponse response, int size) {
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
try {
ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
cs.setBackgroundFactory(new SingleColorBackgroundFactory(VerifycodeUtils.getRandColor(200, 230)));
cs.setColorFactory(new SingleColorFactory(VerifycodeUtils.getRandColor(110, 180)));
cs.setFilterFactory(
new CurvesRippleFilterFactory(new SingleColorFactory(VerifycodeUtils.getRandColor(150, 200))));
RandomWordFactory wordFactory = new RandomWordFactory();
wordFactory.setMaxLength(size);
wordFactory.setMinLength(size);
cs.setWordFactory(wordFactory);
// 强制获取session
HttpSession session = request.getSession(true);
OutputStream out = response.getOutputStream();
String verifycode = EncoderHelper.getChallangeAndWriteImage(cs, "png", out);
logger.info("生成图片验证码,verifycode={}", verifycode);
// 将认证码存入SESSION
session.setAttribute("verifycode", verifycode);
out.flush();
out.close();
} catch (IOException ex) {
logger.error("生成验证码图片出错", ex);
}
}
public static void makeVerifyImageByNum(HttpServletRequest request, HttpServletResponse response, int codeCount) {
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
int width = 60, height = 20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
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.PLAIN, 18));
// 画边框
// g.setColor(new Color());
// g.drawRect(0,0,width-1,height-1);
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
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);
}
char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
StringBuffer sbud = new StringBuffer();
for (int i = 0; i < codeCount; i++) {
String rand = String.valueOf(codeSequence[random.nextInt(36)]);
sbud.append(rand);
// 将认证码显示到图象中
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand, 13 * i + 6, 16);
}
// 强制获取session
HttpSession session = request.getSession(true);
// 将认证码存入SESSION
if(sbud!=null&&sbud.length()>0){
session.setAttribute("verifycode", sbud.toString());
}
// 图象生效
g.dispose();
// 输出图象到页面
try {
OutputStream out = response.getOutputStream();
if(image!=null){
ImageIO.write(image, "JPEG", out);
}
if (null != out) {
out.flush();
out.close();
}
} catch (IOException ex) {
logger.error("生成验证码图片出错", ex);
}
}
public static String getVerifyCodeBySession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return "";
}
if (session.getAttribute("verifycode") == null) {
return "";
}
return session.getAttribute("verifycode").toString();
}
protected static 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);
}
}
......@@ -23,6 +23,11 @@
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required="">
<input class="proving validate[required]" id="MsgCode" name="msgCode" type="text" placeholder="请输入验证码"/>
<p class="provingImg"><img th:src="@{/loadverify}" style="margin-right: 0px;" class="get_yzm img img_pointer" alt="图片验证"
id="verify_codeid"/></p>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
......@@ -62,5 +67,16 @@ button {
function go(){
location.href="/web/bpm/user/toRegister";
}
//点击跟新验证码
$("#verify_codeid").click(function () {
loadVerifyCode();
})
function loadVerifyCode() {
var url = "/loadverify";
$("#verify_codeid").attr("src", url + "?" + Date.parse(new Date()));
}
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment