Spring Security 이미지 인증 코드 기능 의 인 스 턴 스 코드

인증번호 논리
예전 에 프로젝트 에서 도 인증 코드 를 만 들 었 는데 인증 코드 를 만 드 는 코드 가 인터넷 에 많 았 고 제3자 jar 패키지 도 예 쁜 인증 코드 를 만 들 수 있 었 습 니 다.인증 코드 논 리 는 간단 합 니 다.로그 인 페이지 에 image 라벨 을 놓 는 것 입 니 다.src 는 contrller 를 가리 키 고 있 습 니 다.이 Controller 는 생 성 된 그림 을 출력 으로 페이지 에 되 돌려 주 고 그림 을 생 성 하 는 동시에 그림 의 텍스트 를 session 에 두 고 로그 인 할 때 입력 한 인증 코드 를 가 져 와 session 에서 꺼 냅 니 다.두 가 지 를 비교 합 니 다.이 선생님 께 서 말씀 하 시 는 Spring Security 로 인증 코드 를 통합 하 는 것 은 대체적으로 제 가 말 한 것 과 같 지만 더욱 규범화 되 고 통용 되 는 것 입 니 다.
spring security 는 일련의 필터 체인 이기 때문에 인증 코드 도 필터 라 고 밝 혔 습 니 다.필터 체인 의 로그 인 필터 전에 이상 류 를 사용자 정의 하여 인증 코드 의 오류 정보 에 응답 합 니 다.

코드 구조:
인증 코드 는 core 프로젝트 에 두 고 browser 프로젝트 에서 설정 합 니 다.

주 코드:
1,ImageCode:
 먼저 이미지 코드 류,인증 코드 이미지,텍스트,만 료 시간 을 봉인 합 니 다.

package com.imooc.security.core.validate.code;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
 *    
 * ClassName: ImageCode 
 * @Description:    
 * @author lihaoyang
 * @date 2018 3 1 
 */
public class ImageCode {
 private BufferedImage image;
 private String code;
 private LocalDateTime expireTime;//     
 /**
 * 
 * <p>Description: </p>
 * @param image
 * @param code
 * @param expireTn      
 */
 public ImageCode(BufferedImage image, String code, int expireTn) {
 super();
 this.image = image;
 this.code = code;
 //    =    +     
 this.expireTime = LocalDateTime.now().plusSeconds(expireTn);
 }
 public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
 super();
 this.image = image;
 this.code = code;
 this.expireTime = expireTime;
 }
 /**
 *        
 * @Description:        
 * @param @return true   ,false    
 * @return boolean true   ,false    
 * @throws
 * @author lihaoyang
 * @date 2018 3 2 
 */
 public boolean isExpired(){
 return LocalDateTime.now().isAfter(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;
 }
}
Verify Code:인증 코드 를 만 드 는 도구 류 입 니 다.여기http://www.cnblogs.com/lihaoyang/p/7131512.html에서 도 제3자 jar 가방 을 사용 할 수 있 습 니 다.괜 찮 습 니 다.
ValidateCode 예외:봉인 인증번호 이상

/** 
 * @Title: ValidateCodeException.java
 * @Package com.imooc.security.core.validate.code
 * @Description: TODO
 * @author lihaoyang
 * @date 2018 3 2 
 */
package com.imooc.security.core.validate.code;
import org.springframework.security.core.AuthenticationException;
/**
 * ClassName: ValidateCodeException 
 * @Description:        ,  spring security     
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ValidateCodeException extends AuthenticationException {
 /**
 * @Fields serialVersionUID : TODO
 */
 private static final long serialVersionUID = 1L;
 public ValidateCodeException(String msg) {
 super(msg);
 }
}
Validate CodeFilter:인증 코드 필터
논리:Once PerRequestFilter 를 계승 하여 필터 가 매번 한 번 만 호출 될 수 있 도록 합 니 다(왜 그런 지 잘 모 르 겠 습 니 다).인증 실패 프로 세 서 를 주입 하고 검증 에 실 패 했 을 때 호출 합 니 다.

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.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;
/**
 *           
 * ClassName: ValidateCodeFilter 
 * @Description:
 * OncePerRequestFilter:spring     ,              
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ValidateCodeFilter extends OncePerRequestFilter{
 //       
 private AuthenticationFailureHandler authenticationFailureHandler;
 //  session   
 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);
 }
 /**
 *      
 * @Description:      
 * @param @param request
 * @param @throws ServletRequestBindingException 
 * @return void 
 * @throws ValidateCodeException
 * @author lihaoyang
 * @date 2018 3 2 
 */
 private void validate(ServletWebRequest request) throws ServletRequestBindingException {
 //  session  ImageCode  
 ImageCode imageCodeInSession = (ImageCode) sessionStrategy.getAttribute(request, ValidateCodeController.SESSION_KEY);
 //         
 String imageCodeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(), "imageCode");
 //  
 if(StringUtils.isBlank(imageCodeInRequest)){
  throw new ValidateCodeException("       ");
 }
 if(imageCodeInSession == null){
  throw new ValidateCodeException("      ,      ");
 }
 if(imageCodeInSession.isExpired()){
  // session        
  sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
  throw new ValidateCodeException("      ,      ");
 }
 if(!StringUtils.equalsIgnoreCase(imageCodeInSession.getCode(), imageCodeInRequest)){
  throw new ValidateCodeException("     ");
 }
 //    ,  session    
 sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY);
 }
 public AuthenticationFailureHandler getAuthenticationFailureHandler() {
 return authenticationFailureHandler;
 }
 public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
 this.authenticationFailureHandler = authenticationFailureHandler;
 }
}
ValidateCodeController:인증 코드 생 성 제어

package com.imooc.security.core.validate.code;
import java.io.IOException;
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;
/**
 *    Control
 * ClassName: ValidateCodeController 
 * @Description: TODO
 * @author lihaoyang
 * @date 2018 3 1 
 */
@RestController
public class ValidateCodeController {
 public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE"; 
 //  session
 private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
 @GetMapping("/verifycode/image")
 public void createCode(HttpServletRequest request,HttpServletResponse response) throws IOException{
 ImageCode imageCode = createImageCode(request, response);
 sessionStrategy.setAttribute(new ServletWebRequest(request), SESSION_KEY, imageCode);
 ImageIO.write(imageCode.getImage(), "JPEG", response.getOutputStream());
 }
 private ImageCode createImageCode(HttpServletRequest request, HttpServletResponse response) {
 VerifyCode verifyCode = new VerifyCode();
 return new ImageCode(verifyCode.getImage(),verifyCode.getText(),60);
 }
}
BrowserSecurity Config 에서 필터 설정:

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.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;
 //   org.springframework.security.crypto.password.PasswordEncoder
 @Bean
 public PasswordEncoder passwordencoder(){
 //BCryptPasswordEncoder implements PasswordEncoder
 return new BCryptPasswordEncoder();
 }
 //   :       
 @Override
 protected void configure(HttpSecurity http) throws Exception {
 //      
 ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
 //                
 validateCodeFilter.setAuthenticationFailureHandler(imoocAuthenticationFailureHandler);
 
 //               ,  =  +  
 //http.httpBasic() //           
 //
 http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)//                
  .formLogin() //    
  .loginPage("/authentication/require") //      BrowserSecurityController
  //     UsernamePasswordAuthenticationFilter     url "/login",    
  .loginProcessingUrl("/authentication/form") 
  .successHandler(imoocAuthenticationSuccessHandler)//          
  .failureHandler(imoocAuthenticationFailureHandler) //        
  .and()
  .authorizeRequests() //          
  // /authentication/require:    ,securityProperties.getBrowser().getLoginPage():        
  .antMatchers("/authentication/require",
   securityProperties.getBrowser().getLoginPage(),//        ,    
   "/verifycode/image").permitAll() //   
  .anyRequest() //    
  .authenticated() //       
  .and()
  .csrf().disable() //  csrf  
  ; 
 }
}
로그 인 페이지:로그 인 페이지 는 비교적 거 칠 게 만 들 었 습 니 다.그 실험 증 코드 는 인증 코드 input 가 초점 을 잃 었 을 때 검증 할 수 있 고 그림 을 클릭 하여 인증 코드 를 새로 고 칠 수 있 습 니 다.여 기 는 하지 않 습 니 다.

<body>
 demo    . <br>
 <form action="/authentication/form" method="post">
 <table>
  <tr>
  <td>   :</td>
  <td><input type="text" name="username"/></td>
  <td></td>
  </tr>
  <tr>
  <td>  :</td>
  <td><input type="password" name="password"/></td>
  <td></td>
  </tr>
  <tr>
  <td>   :</td>
  <td>
   <input width="100" type="text" name="imageCode"/>
  </td>
  <td>
   <img src="/verifycode/image"/>
  </td>
  </tr>
  <tr>
  <td colspan="2" align="right"><button type="submit">  </button></td>
  </tr>
 </table>
 </form>
 </body>
방문http://localhost:8080/demo-login.html:

사용자 정의 이상 정보 응답

대체 기능 은 이미 문제 가 없다.그러나 통용 되 지 않 습 니 다.예 를 들 어 인증 코드 그림 의 너비 가 높 고 기한 이 지난 시간,여과 한 url,인증 코드 는 논리 적 으로 모두 죽은 것 입 니 다.이것들 은 살 아 있 는 것 으로 만 들 수 있 는데,지금 은 인증 코드 를 필터 로 만 드 는 장점 이 나 타 났 다.필터 가 필요 한 url 을 설정 할 수 있 습 니 다.로그 인 페이지 뿐만 아니 라 인증 코드 가 필요 할 수도 있 습 니 다.
1.유 니 버 설 개조 의 인증 코드 기본 매개 변 수 는 배합 할 수 있 습 니 다.
설정 가능 한 것 으로 만 듭 니 다.그 응용 프로그램 은 이 모듈 을 참조 합 니 다.그 는 스스로 설정 하고 설정 하지 않 으 면 기본 설정 을 사용 합 니 다.그리고 설정 은 요청 url 에서 설명 할 수도 있 고 응용 프로그램 에서 설명 할 수도 있 습 니 다.선생님 은 확실히 선생님 이 고 코드 의 유 니 버 설 이 정말 좋 습 니 다!

실현 하고 자 하 는 효 과 는 application.properties 에서 이러한 설정 을 하 는 것 입 니 다.

#       、 、    
imooc.security.code.image.width = 100
imooc.security.code.image.height = 30
imooc.security.code.image.length = 6
그 다음 에 인증 코드 의 효 과 를 제어 할 수 있 습 니 다.인증 코드 는 이미지 인증 코드,문자 인증 코드 로 나 뉘 기 때문에 1 급.code.image 를 더 만 들 었 습 니 다.이것 은 springboot 의 사용자 정의 설정 파일 을 사 용 했 습 니 다.해당 하 는 자바 류 를 설명 해 야 합 니 다.

Security Properties 에서 code 속성 을 설명 해 야 합 니 다:

package com.imooc.security.core.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 *       
 * ClassName: SecurityProperties 
 * @Description:       
 *       application.properties    imooc.security      
 * 
 * imooc.security.browser.loginPage = /demo-login.html
 *    browser       BrowserProperties  
 *        ,            
 * @author lihaoyang
 * @date 2018 2 28 
 */
@ConfigurationProperties(prefix="imooc.security")
public class SecurityProperties {
 private BrowserProperties browser = new BrowserProperties();
 private ValidateCodeProperties code = new ValidateCodeProperties();
 public BrowserProperties getBrowser() {
 return browser;
 }
 public void setBrowser(BrowserProperties browser) {
 this.browser = browser;
 }
 public ValidateCodeProperties getCode() {
 return code;
 }
 public void setCode(ValidateCodeProperties code) {
 this.code = code;
 }
}
ValidateCodeProperties:

package com.imooc.security.core.properties;
/**
 *      
 * ClassName: ValidateCodeProperties 
 * @Description:      ,         、      ,      
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ValidateCodeProperties {
 //    
 private ImageCodeProperties image = new ImageCodeProperties();
 public ImageCodeProperties getImage() {
 return image;
 }
 public void setImage(ImageCodeProperties image) {
 this.image = image;
 }
}
ImageCodeProperties:

package com.imooc.security.core.properties;
/**
 *         
 * ClassName: ImageCodeProperties 
 * @Description:         
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ImageCodeProperties {
 //   
 private int width = 67;
 //   
 private int height = 23;
 //       
 private int length = 4;
 //    
 private int expireIn = 60;
 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;
 }
}
요청 단계 의 설정 입 니 다.요청 에 인증 코드 가 있 는 인자 가 있 으 면 요청 에 있 는 것 을 사용 하 십시오:

Validate CodeController 의 createImageCode 방법 을 제어 하여 요청 매개 변수 에 이러한 매개 변수 가 있 는 지 판단 하고 있 으 면 인증 코드 생 성 류 Verify Code 에 전송 하여 생 성 할 때 동적 으로 제어 할 수 있 습 니 다.

private ImageCode createImageCode(HttpServletRequest request, HttpServletResponse response) {
 //  request       、 、      ,     ,      
 int width = ServletRequestUtils.getIntParameter(request, "width",securityProperties.getCode().getImage().getWidth());
 
 int height = ServletRequestUtils.getIntParameter(request, "height",securityProperties.getCode().getImage().getHeight());
 
 int charLength = this.securityProperties.getCode().getImage().getLength();
 VerifyCode verifyCode = new VerifyCode(width,height,charLength);
 return new ImageCode(verifyCode.getImage(),verifyCode.getText(),this.securityProperties.getCode().getImage().getExpireIn());
 }
VerifyCode:

public VerifyCode(int w, int h, int charLength) {
 super();
 this.w = w;
 this.h = h;
 this.charLength = charLength;
 }
실험:demo 프로젝트 에서 응용 단계 설정 하기

요청 레벨 설정

<img src="/verifycode/image?width=200"/>
접근:

길 이 는 요청 밴드 의 인자 200,높이 는 30,문 자 는 설정 한 6 개 입 니 다.
2.유 니 버 설 개조 인증 코드 차단 인터페이스 설정 가능
먼저 필요 한 효 과 는 다음application.properties에서 차단 해 야 할 인 터 페 이 스 를 동적 으로 설정 할 수 있 습 니 다.
ImageCodeProperties속성 이 추가 되 었 습 니 다:private String url;/위의 그림 설정 과 일치 하도록 차단 한 url 입 니 다.
핵심,인증 코드 필터 수정 필요:
1.차단기 에 set 집합 을 표시 하여 설정 파일 에 설정 할 차단 이 필요 한 url 을 저장 합 니 다.
2.InitializingBean 인 터 페 이 스 를 실현 합 니 다.목적:다른 매개 변수 가 모두 조립 되 었 을 때 차단 해 야 할 urls 의 값 을 초기 화하 고 after PropertiesSet 방법 을 다시 씁 니 다.
3,보안 속성 주입,프로필 읽 기
4.AntPathMatcher 도구 류 를 예화 합 니 다.이것 은 일치 기 입 니 다.
5.browser 프로젝트 의 BrowserSecurity Config 에 after PropertiesSet 방법 을 설정 합 니 다.
6.이 모듈 의 demo 프로젝트 를 참조 하 는 application.properties 에 걸 러 낼 url 을 설정 합 니 다.
ValidateCodeFilter:

/**
 *           
 * ClassName: ValidateCodeFilter 
 * @Description:
 *   OncePerRequestFilter:spring     ,              
 *    InitializingBean     :
 *              ,        urls  
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ValidateCodeFilter extends OncePerRequestFilter implements InitializingBean{
 //       
 private AuthenticationFailureHandler authenticationFailureHandler;
 //  session   
 private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
 //     url  
 private Set<String> urls = new HashSet<>();
 //    
 private SecurityProperties securityProperties;
 //spring   
 private AntPathMatcher antPathMatcher = new AntPathMatcher();
 @Override
 public void afterPropertiesSet() throws ServletException {
 super.afterPropertiesSet();
 //        urls
 String[] configUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(securityProperties.getCode().getImage().getUrl(), ",");
 for (String configUrl : configUrls) {
  urls.add(configUrl);
 }
 //         
 urls.add("/authentication/form");
 }
 @Override
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  throws ServletException, IOException {
 /**
  *          
  *      url          ,       
  */
 boolean action = false;
 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 ;//    ,        
  }
 }
 //      ,        
 filterChain.doFilter(request, response);
 }
 //      ,,,
}
BrowserSecurityConfig:

url 설정:

#          
imooc.security.code.image.url = /user,/user/*
테스트:/user  /user/1 이 차단 되 었 습 니 다.


로그 인 페이지 에 접근 하고 인증 코드 를 쓰 지 않 습 니 다:

예상 과 일치 하 다.이로써 동적 설정 차단 인터페이스 가 완료 되 었 습 니 다.
3,인증 코드 생 성 논리 설정 가능
 비교적 잘 작 성 된 프로그램 은 일반적으로 인 터 페 이 스 를 개방 하여 사용자 가 사용자 정의 로 실현 할 수 있 도록 합 니 다.실현 되 지 않 으 면 기본 적 인 실현 으로 이 일 을 하고 인증 코드 의 생 성 을 스스로 실현 할 수 있 도록 합 니 다.인증 코드 생 성 논 리 를 설정 가능 한 것 으로 만 들 려 면 이미지 인증 코드 생 성기 류 만 쓸 수 없습니다.인증 코드 생 성 을 인터페이스 Validate CodeGenerator 로 추출 하고 인증 코드 를 생 성 하 는 방법 generator()가 필요 합 니 다.인증 코드 는 이미지 인증 코드,문자 인증 코드 등 이 있 기 때문에 저 희 는 자신의 인증 모듈 에서 기본 적 인 실현 을 합 니 다.예 를 들 어 이미지 인증 코드 의 실현 ImageCodeGenerator,ImageCodeGenerator 에서 저 희 는 이 클래스 에@Component 주 해 를 추가 하지 않 습 니 다.그 다음 에 인증 코드 bean 을 쓰 는 설정 류 Validate CodeBeanConfig 를 사용 합 니 다.이 설정 류 는 이미지 인증 코드 가 imageCodeGenerator,문자 인증 코드 등 필요 한 인증 코드 를 설정 합 니 다.그들 은 반환 유형 은 모두 Validate CodeGenerator 이 고@Conditional OnMissingBean(name="imageCodeGenerator")주 해 를 사용 합 니 다.현재 spring 용기 에 imageCodeGenerator 라 는 bean 이 있 을 때 사용 하고 없 으 면 다시 설정 하 는 것 을 판단 할 수 있 습 니 다.그러면 다른 사람 이 이 모듈 을 인용 하면 다른 사람 이 인증 코드 를 실현 하여 Validate CodeGenerator 인 터 페 이 스 를 만 들 면 실현 클래스 의 name 을 imageCodeGenerator 로 설정 하고 그들의 실현 으로 설정 합 니 다.이렇게 해서 프로그램의 확장 성 을 해 냈 다.

 주 코드:
코드 생 성기 인터페이스 ValidateCodeGenerator:

package com.imooc.security.core.validate.code;
import org.springframework.web.context.request.ServletWebRequest;
/**
 *        
 * ClassName: ValidateCodeGenerator 
 * @Description: TODO
 * @author lihaoyang
 * @date 2018 3 2 
 */
public interface ValidateCodeGenerator {

 /**
 *          
 * @Description: TODO
 * @param @param request
 * @param @return 
 * @return ImageCode 
 * @throws
 * @author lihaoyang
 * @date 2018 3 2 
 */
 ImageCode generator(ServletWebRequest request);
}
이미지 인증 코드 생 성 기 는 ImageCodeGenerator 를 실현 합 니 다.

package com.imooc.security.core.validate.code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import com.imooc.security.core.properties.SecurityProperties;
/**
 *         
 * ClassName: ImageCodeGenerator 
 * @Description: TODO
 * @author lihaoyang
 * @date 2018 3 2 
 */
public class ImageCodeGenerator implements ValidateCodeGenerator {
 @Autowired
 private SecurityProperties securityProperties;
 @Override
 public ImageCode generator(ServletWebRequest request) {
 //  request       、 、      ,     ,      
 int width = ServletRequestUtils.getIntParameter(request.getRequest(), "width",securityProperties.getCode().getImage().getWidth());
 int height = ServletRequestUtils.getIntParameter(request.getRequest(), "height",securityProperties.getCode().getImage().getHeight());
 int charLength = this.securityProperties.getCode().getImage().getLength();
 VerifyCode verifyCode = new VerifyCode(width,height,charLength);
 return new ImageCode(verifyCode.getImage(),verifyCode.getText(),this.securityProperties.getCode().getImage().getExpireIn());
 }
 public SecurityProperties getSecurityProperties() {
 return securityProperties;
 }
 public void setSecurityProperties(SecurityProperties securityProperties) {
 this.securityProperties = securityProperties;
 }
}
ValidateCodeBeanConfig:

package com.imooc.security.core.validate.code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.imooc.security.core.properties.SecurityProperties;
/**
 *          ValidateCodeGenerator       Bean
 * ClassName: ValidateCodeBeanConfig 
 * @Description: 
 *          ValidateCodeGenerator       Bean
 *          、        
 * @author lihaoyang
 * @date 2018 3 5 
 */
@Configuration
public class ValidateCodeBeanConfig {
 @Autowired
 private SecurityProperties securityProperties;
 /**
 * @Description: 
 * @ConditionalOnMissingBean      spring     imageCodeGenerator        bean
 *             ,        core  ,     ,          
 *           ,   ValidateCodeGenerator  ,        ,    imageCodeGenerator ,
 *          ,            。
 * @param @return 
 * @return ValidateCodeGenerator 
 * @throws
 * @author lihaoyang
 * @date 2018 3 5 
 */
 @Bean
 @ConditionalOnMissingBean(name="imageCodeGenerator") 
 public ValidateCodeGenerator imageCodeGenerator(){ 
 ImageCodeGenerator codeGenerator = new ImageCodeGenerator();
 codeGenerator.setSecurityProperties(securityProperties);
 return codeGenerator;
 }
}
이렇게 해서 만약 에 어느 모듈 이 이 인증 코드 모듈 을 인용 했다 면 그 는 다음 과 같은 실현 을 사용자 정의 했다.

package com.imooc.code;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;
import com.imooc.security.core.validate.code.ImageCode;
import com.imooc.security.core.validate.code.ValidateCodeGenerator;
@Component("imageCodeGenerator")
public class DemoImageCodeGenerator implements ValidateCodeGenerator {
 @Override
 public ImageCode generator(ServletWebRequest request) {
 System.err.println("demo          ,,,");
 return null;
 }
}
이렇게 하면 Validate CodeBeanConfig 는 인증 코드 bean 을 설정 할 때 사용자 정의 로 이 루어 집 니 다.
전체 코드 를 github 에 두 었 습 니 다:https://github.com/lhy1234/spring-security
총결산
위 에서 말 한 것 은 소 편 이 소개 한 Spring Security 이미지 인증 코드 기능 의 인 스 턴 스 코드 입 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기