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();
}
}
UPDATE T_GWSD_SETTING T
SET T.KSSJ = #{kssj},
T.JSSJ = #{jssj}
WHERE T.NAME = '白班'
UPDATE T_GWSD_SETTING T
SET T.KSSJ = #{kssj},
T.JSSJ = #{jssj}
WHERE T.NAME = '夜班'
INSERT INTO T_WFXW_SCORE
JDBH,
JDMC,
WFDM,
YSJD,
JDQZ,
SJJD,
JDSM,
SJLY,
LRR,
LRSJ,
GXR,
ZNJTPOSTMAN.FPOSTMAN_NEXTVAL('SEQ_T_WFXW_SCORE_CODE'),
#{jdmc,jdbcType=VARCHAR},
#{wfdm,jdbcType=VARCHAR},
#{ysjd,jdbcType=INTEGER},
#{jdqz,jdbcType=INTEGER},
#{sjjd,jdbcType=INTEGER},
#{jdsm,jdbcType=VARCHAR},
#{sjly,jdbcType=VARCHAR},
#{lrr,jdbcType=VARCHAR},
SYSDATE,
#{gxr,jdbcType=VARCHAR},
DELETE T_WFXW_FL T
WHERE T.WFLX = #{wffl,jdbcType=VARCHAR}
AND T.WFXW = #{wfxw,jdbcType=VARCHAR}
INSERT INTO T_WFXW_FL
WFLX,
WFXW,
SFXS,
PX,
LRR,
LRSJ
#{wflx,jdbcType=VARCHAR},
#{wfxw,jdbcType=VARCHAR},
#{sfxs,jdbcType=INTEGER},
#{px,jdbcType=INTEGER},
#{lrr,jdbcType=VARCHAR},
sysdate
UPDATE T_WFXW_FL
WFLX = #{wflx,jdbcType=VARCHAR},
WFXW = #{wfxw,jdbcType=VARCHAR},
SFXS = #{sfxs,jdbcType=VARCHAR},
PX = #{px,jdbcType=VARCHAR},
LRR = #{lrr,jdbcType=VARCHAR},
WHERE WFLX = #{originalwflx,jdbcType=VARCHAR}
AND WFXW = #{originalwfxw,jdbcType=VARCHAR}
UPDATE T_WFXW_SCORE
JDMC=#{jdmc,jdbcType=VARCHAR},
WFDM=#{wfdm,jdbcType=VARCHAR},
YSJD=#{ysjd,jdbcType=INTEGER},
JDQZ=#{jdqz,jdbcType=INTEGER},
SJJD=#{sjjd,jdbcType=INTEGER},
JDSM= #{jdsm,jdbcType=VARCHAR},
SJLY=#{sjly,jdbcType=VARCHAR},
GXR=#{gxr,jdbcType=VARCHAR},
GXSJ=SYSDATE,
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
DELETE FROM T_WFXW_SCORE
WHERE JDBH
IN
#{item,jdbcType=VARCHAR}
INSERT INTO T_JCJ_SCORE
JDBH,
JDMC,
YSJD,
JDQZ,
SJJD,
#{jdbh,jdbcType=VARCHAR},
#{jdmc,jdbcType=VARCHAR},
#{ysjd,jdbcType=INTEGER},
#{jdqz,jdbcType=INTEGER},
#{sjjd,jdbcType=INTEGER},
UPDATE T_JCJ_SCORE
JDMC=#{jdmc,jdbcType=VARCHAR},
YSJD=#{ysjd,jdbcType=INTEGER},
JDQZ=#{jdqz,jdbcType=INTEGER},
SJJD=#{sjjd,jdbcType=INTEGER},
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
DELETE FROM T_JCJ_SCORE
WHERE JDBH
IN
#{item,jdbcType=VARCHAR}
INSERT INTO T_QW_SCORE
JDBH,
JDMC,
YSJD,
JDQZ,
SJJD,
#{jdbh,jdbcType=VARCHAR},
#{jdmc,jdbcType=VARCHAR},
#{ysjd,jdbcType=INTEGER},
#{jdqz,jdbcType=INTEGER},
#{sjjd,jdbcType=INTEGER},
UPDATE T_QW_SCORE
JDMC=#{jdmc,jdbcType=VARCHAR},
YSJD=#{ysjd,jdbcType=INTEGER},
JDQZ=#{jdqz,jdbcType=INTEGER},
SJJD=#{sjjd,jdbcType=INTEGER},
WHERE JDBH = #{jdbh,jdbcType=VARCHAR}
DELETE FROM T_QW_SCORE
WHERE JDBH
IN
#{item,jdbcType=VARCHAR}
访问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
啊,我又来了,追评.....
这里我们要对图片验证进行重构,可以定义设置验证码图片width,height,和验证码长度,以及设置哪些页面需要验证。
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);
validateCodeFilter.setSecurityProperties(securityProperties);
validateCodeFilter.afterPropertiesSet();
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.core.properties;
public class ImageCodeProperties {
private int width = 67;
private int height = 23;
private int length = 4;
private int expireIn = 60;
private String url;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getExpireIn() {
return expireIn;
}
public void setExpireIn(int expireIn) {
this.expireIn = expireIn;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
package com.imooc.security.core.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="imooc.security")
public class SecurityProperties {
private BrowserProperties browser = new BrowserProperties();
private ValidateCodeProperties code = new ValidateCodeProperties();
public BrowserProperties getBrowsers() {
return browser;
}
public void setBrowsers(BrowserProperties browsers) {
this.browser = browsers;
}
public ValidateCodeProperties getCode() {
return code;
}
public void setCode(ValidateCodeProperties code) {
this.code = code;
}
}
package com.imooc.security.core.properties;
public class ValidateCodeProperties {
private ImageCodeProperties image = new ImageCodeProperties();
public ImageCodeProperties getImage() {
return image;
}
public void setImage(ImageCodeProperties image) {
this.image = image;
}
}
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.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import com.imooc.security.core.properties.SecurityProperties;
@RestController
public class ValidateCodeController {
public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
@Autowired
private SecurityProperties securityProperties;
@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) {
//第一步 生成随机验证码 可以去网上搜
//宽度和高度先从请求中取 如果请求没有则使用默认配置 (可在demo配置文件改变你默认配置)
int width=ServletRequestUtils.getIntParameter(request, "width", securityProperties.getCode().getImage().getWidth());//宽和高
int height=ServletRequestUtils.getIntParameter(request, "height", securityProperties.getCode().getImage().getHeight());
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 < securityProperties.getCode().getImage().getLength(); 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,securityProperties.getCode().getImage().getExpireIn());//有效期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 org.springframework.security.core.AuthenticationException;
public class ValidateCodeException extends AuthenticationException {
/**
*
*/
private static final long serialVersionUID = 1L;
public ValidateCodeException(String msg) {
super(msg);
}
}
package com.imooc.security.core.validate.code;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
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.InitializingBean;
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.util.AntPathMatcher;
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;
import com.imooc.security.core.properties.SecurityProperties;
public class ValidateCodeFilter extends OncePerRequestFilter implements InitializingBean{
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
private Set urls = new HashSet();
@Autowired
private SecurityProperties securityProperties;
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public void afterPropertiesSet() throws ServletException {
String [] configUrls = StringUtils.splitByWholeSeparator(securityProperties.getCode().getImage().getUrl(), ",");
for(String url:configUrls) {
urls.add(url);
}
urls.add("/authentication/form");
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
boolean action = false;
logger.info("urls的长度是:"+urls.size()+"它们是:"+urls.toString());
logger.info("requestUri是:"+request.getRequestURI());
for(String url:urls) {
if (antPathMatcher.match(url, request.getRequestURI())) {
action = true;
}
}
if (action) {
try {
//校验逻辑
validate(new ServletWebRequest(request));
} catch (ValidateCodeException e) {
authenticationFailureHandler.onAuthenticationFailure(request, response, e);
return;
}
}
/*//主干逻辑
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;
}
public Set getUrls() {
return urls;
}
public void setUrls(Set urls) {
this.urls = urls;
}
public SecurityProperties getSecurityProperties() {
return securityProperties;
}
public void setSecurityProperties(SecurityProperties securityProperties) {
this.securityProperties = securityProperties;
}
}
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/imooc-demo?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username = root
spring.datasource.password = 123456
spring.session.store-type = none
#security.basic.enabled = false
server.port = 8060
imooc.security.browser.loginPage=/demo-signIn.html
imooc.security.browser.loginType=REDIRECT
imooc.security.code.image.length=6
imooc.security.code.image.width=100
imooc.security.code.image.url= /user,/user/*
启动测试一下:
看一下前台输出路径情况:
源码去看我的上传资源找图片验证重构下载就好。