SpringSecurity中怎么實現(xiàn)驗證碼登錄功能,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
網(wǎng)站建設哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、小程序設計、集團企業(yè)網(wǎng)站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了同江免費建站歡迎大家使用!
1、添加生成驗證碼的控制器。
(1)、生成驗證碼
/** * 引入 Security 配置屬性類 */ @Autowired private SecurityProperties securityProperties; @Override public ImageCode createCode(HttpServletRequest request ) { //如果請求中有 width 參數(shù),則用請求中的,否則用 配置屬性中的 int width = ServletRequestUtils.getIntParameter(request,"width",securityProperties.getWidth()); //高度(寬度) int height = ServletRequestUtils.getIntParameter(request,"height",securityProperties.getHeight()); //圖片驗證碼字符個數(shù) 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); //將隨機數(shù) 放到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; /** * 隨機數(shù) */ 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; /** * 長度(幾個數(shù)字) */ 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(); /** * 創(chuàng)建一個Set 集合 存放 需要驗證碼的 urls */ private Set
3、在核心配置BrowserSecurityConfig中添加過濾器配置
@Autowired private ValidateCodeFilter validateCodeFilter; @Override protected void configure(HttpSecurity http) throws Exception { //在UsernamePasswordAuthenticationFilter 過濾器前 加一個過濾器 來搞驗證碼 http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) //表單登錄 方式 .formLogin() .loginPage("/authentication/require") //登錄需要經(jīng)過的url請求 .loginProcessingUrl("/authentication/form") .passwordParameter("pwd") .usernameParameter("user") .successHandler(mySuccessHandler) .failureHandler(myFailHandler) .and() //請求授權(quán) .authorizeRequests() //不需要權(quán)限認證的url .antMatchers("/authentication/*","/code/image").permitAll() //任何請求 .anyRequest() //需要身份認證 .authenticated() .and() //關(guān)閉跨站請求防護 .csrf().disable(); //默認注銷地址:/logout http.logout(). //注銷之后 跳轉(zhuǎn)的頁面 logoutSuccessUrl("/authentication/require"); }
4、異常輔助類
public class ValidateCodeException extends AuthenticationException { public ValidateCodeException(String msg, Throwable t) { super(msg, t); } public ValidateCodeException(String msg) { super(msg); }}
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。