亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringSecurity中怎么實現驗證碼登錄功能

發布時間:2021-08-06 16:21:47 來源:億速云 閱讀:114 作者:Leah 欄目:編程語言

SpringSecurity中怎么實現驗證碼登錄功能,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

1、添加生成驗證碼的控制器。

(1)、生成驗證碼

/**   * 引入 Security 配置屬性類   */  @Autowired  private SecurityProperties securityProperties;  @Override  public ImageCode createCode(HttpServletRequest request ) {    //如果請求中有 width 參數,則用請求中的,否則用 配置屬性中的    int width = ServletRequestUtils.getIntParameter(request,"width",securityProperties.getWidth());    //高度(寬度)    int height = ServletRequestUtils.getIntParameter(request,"height",securityProperties.getHeight());    //圖片驗證碼字符個數    int length = securityProperties.getLength();    //過期時間    int expireIn = securityProperties.getExpireIn();    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.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 < length; 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, expireIn);  }  /**   * 生成隨機背景條紋   */  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);  }

(2)、驗證碼控制器

public static final String SESSION_KEY = "SESSION_KEY_IMAGE_CODE";  @Autowired  private ValidateCodeGenerator imageCodeGenerator;  /**   * Session 對象   */  private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();  @GetMapping("/code/image")  public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {    ImageCode imageCode = imageCodeGenerator.createCode(request);    //將隨機數 放到Session中    sessionStrategy.setAttribute(new ServletWebRequest(request),SESSION_KEY,imageCode);    request.getSession().setAttribute(SESSION_KEY,imageCode);    //寫給response 響應    response.setHeader("Cache-Control", "no-store, no-cache");    response.setContentType("image/jpeg");    ImageIO.write(imageCode.getImage(),"JPEG",response.getOutputStream());  }

(3)、其它輔助類

@Datapublic class ImageCode {  /**   * 圖片   */  private BufferedImage image;  /**   * 隨機數   */  private String code;  /**   * 過期時間   */  private LocalDateTime expireTime;  public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {    this.image = image;    this.code = code;    this.expireTime = expireTime;  }  public ImageCode(BufferedImage image, String code, int expireIn) {    this.image = image;    this.code = code;    //當前時間 加上 設置過期的時間    this.expireTime = LocalDateTime.now().plusSeconds(expireIn);  }  public boolean isExpried(){    //如果 過期時間 在 當前日期 之前,則驗證碼過期    return LocalDateTime.now().isAfter(expireTime);  }}

@ConfigurationProperties(prefix = "sso.security.code.image")@Component@Datapublic class SecurityProperties {  /**   * 驗證碼寬度   */  private int width = 67;  /**   * 高度   */  private int height = 23;  /**   * 長度(幾個數字)   */  private int length = 4;  /**   * 過期時間   */  private int expireIn = 60;  /**   * 需要圖形驗證碼的 url   */  private String url;}

(4)、驗證

2、添加過濾器,進行驗證碼驗證

@Component@Slf4jpublic class ValidateCodeFilter extends OncePerRequestFilter implements InitializingBean {  /**   * 登錄失敗處理器   */  @Autowired  private AuthenticationFailureHandler failureHandler;  /**   * Session 對象   */  private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();  /**   * 創建一個Set 集合 存放 需要驗證碼的 urls   */  private Set<String> urls = new HashSet<>();  /**   * spring的一個工具類:用來判斷 兩字符串 是否匹配   */  private AntPathMatcher pathMatcher = new AntPathMatcher();  @Autowired  private SecurityProperties securityProperties;  /**   * 這個方法是 InitializingBean 接口下的一個方法, 在初始化配置完成后 運行此方法   */  @Override  public void afterPropertiesSet() throws ServletException {    super.afterPropertiesSet();    //將 application 配置中的 url 屬性進行 切割    String[] configUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(securityProperties.getUrl(), ",");    //添加到 Set 集合里    urls.addAll(Arrays.asList(configUrls));    //因為登錄請求一定要有驗證碼 ,所以直接 add 到set 集合中    urls.add("/authentication/form");  }  @Override  protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {    boolean action = false;    for (String url:urls){      //如果請求的url 和 配置中的url 相匹配      if (pathMatcher.match(url,httpServletRequest.getRequestURI())){        action = true;      }    }    //攔截請求    if (action){      logger.info("攔截成功"+httpServletRequest.getRequestURI());      //如果是登錄請求      try {        validate(new ServletWebRequest(httpServletRequest));      }catch (ValidateCodeException exception){        //返回錯誤信息給 失敗處理器        failureHandler.onAuthenticationFailure(httpServletRequest,httpServletResponse,exception);        return;      }    }    filterChain.doFilter(httpServletRequest,httpServletResponse);  }  private void validate(ServletWebRequest request) throws ServletRequestBindingException {    //從session中取出 驗證碼    ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(request,ValidateCodeController.SESSION_KEY);    //從request 請求中 取出 驗證碼    String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(),"imageCode");    if (StringUtils.isBlank(codeInRequest)){      logger.info("驗證碼不能為空");      throw new ValidateCodeException("驗證碼不能為空");    }    if (codeInSession == null){      logger.info("驗證碼不存在");      throw new ValidateCodeException("驗證碼不存在");    }    if (codeInSession.isExpried()){      logger.info("驗證碼已過期");      sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY);      throw new ValidateCodeException("驗證碼已過期");    }    if (!StringUtils.equals(codeInSession.getCode(),codeInRequest)){      logger.info("驗證碼不匹配"+"codeInSession:"+codeInSession.getCode() +", codeInRequest:"+codeInRequest);      throw new ValidateCodeException("驗證碼不匹配");    }    //把對應 的 session信息 刪掉    sessionStrategy.removeAttribute(request,ValidateCodeController.SESSION_KEY);  }

3、在核心配置BrowserSecurityConfig中添加過濾器配置

@Autowired  private ValidateCodeFilter validateCodeFilter;  @Override  protected void configure(HttpSecurity http) throws Exception {    //在UsernamePasswordAuthenticationFilter 過濾器前 加一個過濾器 來搞驗證碼    http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)        //表單登錄 方式        .formLogin()        .loginPage("/authentication/require")        //登錄需要經過的url請求        .loginProcessingUrl("/authentication/form")        .passwordParameter("pwd")        .usernameParameter("user")        .successHandler(mySuccessHandler)        .failureHandler(myFailHandler)        .and()        //請求授權        .authorizeRequests()        //不需要權限認證的url        .antMatchers("/authentication/*","/code/image").permitAll()        //任何請求        .anyRequest()        //需要身份認證        .authenticated()        .and()        //關閉跨站請求防護        .csrf().disable();    //默認注銷地址:/logout    http.logout().        //注銷之后 跳轉的頁面        logoutSuccessUrl("/authentication/require");  }

4、異常輔助類

public class ValidateCodeException extends AuthenticationException {  public ValidateCodeException(String msg, Throwable t) {    super(msg, t);  }  public ValidateCodeException(String msg) {    super(msg);  }}

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

常山县| 焦作市| 常宁市| 绥中县| 沐川县| 太和县| 平湖市| 无极县| 酒泉市| 岳阳县| 闵行区| 三穗县| 额济纳旗| 云浮市| 会昌县| 垣曲县| 三都| 凌源市| 合肥市| 广汉市| 内江市| 乌什县| 特克斯县| 二连浩特市| 内乡县| 茌平县| 临清市| 甘南县| 芮城县| 林芝县| 盈江县| 雅江县| 汉川市| 武陟县| 武山县| 彭阳县| 大足县| 隆尧县| 江津市| 德惠市| 古蔺县|