国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Security 圖片驗證碼功能的實例代碼

Spring Security 圖片驗證碼功能的實例代碼

2021-04-09 11:29奮斗的羊仔 Java教程

spring security是一系列的過濾器鏈,所以在這里驗證碼也聲明為過濾器,加在過濾器鏈的 登錄過濾器之前,然后自定義一個異常類,來響應驗證碼的錯誤信息.這篇文章主要介紹了Spring Security 圖片驗證碼,需要的朋友可以參考下

驗證碼邏輯

以前在項目中也做過驗證碼,生成驗證碼的代碼網上有很多,也有一些第三方的jar包也可以生成漂亮的驗證碼。驗證碼邏輯很簡單,就是在登錄頁放一個image標簽,src指向一個controller,這個controller返回把生成的圖片以輸出流返回給頁面,生成圖片的同時把圖片上的文本放在session,登錄的時候帶過來輸入的驗證碼,從session中取出,兩者對比。這位老師講的用spring security集成驗證碼,大體思路和我說的一樣,但更加規范和通用些。

spring security是一系列的過濾器鏈,所以在這里驗證碼也聲明為過濾器,加在過濾器鏈的 登錄過濾器之前,然后自定義一個異常類,來響應驗證碼的錯誤信息。

Spring Security 圖片驗證碼功能的實例代碼

代碼結構:

驗證碼代碼放在core項目,在browser項目做一下配置。

Spring Security 圖片驗證碼功能的實例代碼

主要代碼:

1,imagecode:

 首先是imagecode類,封裝驗證碼圖片、文本、過期時間

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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;
 }
}

verifycode:生成驗證碼的工具類,在這里 http://www.cnblogs.com/lihaoyang/p/7131512.html 當然也可以使用第三方jar包,無所謂。

validatecodeexception:封裝驗證碼異常

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * @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);
 }
}

validatecodefilter:驗證碼過濾器

邏輯:繼承onceperrequestfilter 保證過濾器每次只會被調用一次(不太清楚為什么),注入認證失敗處理器,在驗證失敗時調用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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:生成驗證碼control

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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);
 }
}

browsersecurityconfig里進行過濾器配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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失去焦點的時候做校驗,還可以做個點擊圖片刷新驗證碼功能,這里就不做了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<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

Spring Security 圖片驗證碼功能的實例代碼

響應自定義的異常信息

Spring Security 圖片驗證碼功能的實例代碼

大體功能已經沒問題了。但是不夠通用,比如驗證碼圖片的寬高、過期時間、過濾的url、驗證碼成邏輯都是寫死的。這些可以做成活的,現在把驗證碼做成一個過濾器的好處體現出來了。我們可以配置需要過濾的url,有時候可能不只是登陸頁需要驗證碼,這樣更加通用。

1,通用性改造 之 驗證碼基本參數可配

做成可配置的,那個應用引用該模塊,他自己配置去,不配置就使用默認配置。而且,配置既可以在請求url中聲明,也可以在應用中聲明,老師的確是老師,代碼通用性真好!

Spring Security 圖片驗證碼功能的實例代碼

想要實現的效果是,在application.properties里做這樣的配置:

?
1
2
3
4
#驗證碼 圖片寬、高、字符個數
imooc.security.code.image.width = 100
imooc.security.code.image.height = 30
imooc.security.code.image.length = 6

然后就能控制驗證碼的效果,因為驗證碼還分圖片驗證碼、短信驗證碼,所以多做了一級.code.image,這就用到了springboot的自定義配置文件,需要聲明對應的java類:

Spring Security 圖片驗證碼功能的實例代碼

需要在securityproperties里聲明code屬性:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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;
 }
}

請求級的配置,如果請求里帶的有驗證碼的參數,就用請求里的:

Spring Security 圖片驗證碼功能的實例代碼

在validatecodecontroller的createimagecode方法做控制,判斷請求參數是否有這些參數,有的話,傳給驗證碼生成類verifycode,在生成的時候就能動態控制了。

?
1
2
3
4
5
6
7
8
9
10
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:

?
1
2
3
4
5
6
public verifycode(int w, int h, int charlength) {
 super();
 this.w = w;
 this.h = h;
 this.charlength = charlength;
 }

實驗:在demo項目做應用級配置

Spring Security 圖片驗證碼功能的實例代碼

登錄表單做請求級配置

?
1
<img src="/verifycode/image?width=200"/>

訪問:

Spring Security 圖片驗證碼功能的實例代碼

長度為請求級帶的參數200,高為30,字符為配置的6個。

2,通用性改造 之 驗證碼攔截的接口可配置

先要的效果就是再application.properties里能動態配置需要攔截的接口:

Spring Security 圖片驗證碼功能的實例代碼

imagecodeproperties新增一個屬性:private string url; //攔截的url,來匹配上圖的配置。

核心,驗證碼過濾器需要修改:

1,在攔截器里聲明一個set集合,用來存儲配置文件里配置的需要攔截的urls。

2,實現initializingbean接口,目的: 在其他參數都組裝完畢的時候,初始化需要攔截的urls的值,重寫afterpropertiesset方法來實現。

3,注入securityproperties,讀取配置文件

4,實例化antpathmatcher工具類,這是一個匹配器

5,在browser項目的browsersecurityconfig里設置調用一下afterpropertiesset方法。

6,在引用該模塊的demo項目的application.properties里配置要過濾的url

validatecodefilter:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
 * 處理登錄驗證碼過濾器
 * 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:

Spring Security 圖片驗證碼功能的實例代碼

配置url:

?
1
2
#驗證碼攔截的接口配置
imooc.security.code.image.url = /user,/user/*

測試:/user  /user/1 被攔截了

Spring Security 圖片驗證碼功能的實例代碼

Spring Security 圖片驗證碼功能的實例代碼

訪問登錄頁,不寫驗證碼:

Spring Security 圖片驗證碼功能的實例代碼

和預期一致。至此,動態配置攔截接口完成

3,驗證碼的生成邏輯可配置

 寫的比較好的程序,一般都開放接口,可以讓用戶去自定義實現,如果不實現就用默認的實現,下面來做這件事,使驗證碼的生成可以自己實現。如果要想把驗證碼的生成邏輯做成可配置的,就不能只寫一個圖片驗證碼生成器的類了,需要把驗證碼生成提取成一個接口validatecodegenerator,一個生成驗證碼的方法generator()。因為驗證碼還有圖片驗證碼、短信驗證碼等,這樣,我們在自己的驗證模塊里做一個默認的實現,如圖片驗證碼的實現imagecodegenerator,在imagecodegenerator里我們不在該類上加@component注解。然后使用寫一個驗證碼bean的配置類validatecodebeanconfig,這個配置類配置各種需要的驗證碼實現類bean如圖片驗證碼實現imagecodegenerator、短信驗證碼等,他們返回類型都是validatecodegenerator,使用@conditionalonmissingbean(name="imagecodegenerator")注解,可以判斷如果當前spring容器有名字為imagecodegenerator的bean時,就使用,沒有的話再配置,這樣如果別人引用了你的該模塊,如果別人自己實現了驗證碼生成validatecodegenerator接口,他們配置了實現類的name為imagecodegenerator,就用他們自己的實現,這樣就做到了程序的可擴展性。

Spring Security 圖片驗證碼功能的實例代碼

 主要代碼:

代碼生成器接口validatecodegenerator:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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;
 }
}

這樣,如果哪個模塊引用了這個驗證碼模塊,他自定義了實現,如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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;
 }
}

這樣validatecodebeanconfig在配置驗證碼bean時,就會使用使用者自定義的實現。

完整代碼放在了github:https://github.com/lhy1234/spring-security

總結

以上所述是小編給大家介紹的spring security 圖片驗證碼功能的實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:https://www.cnblogs.com/lihaoyang/archive/2018/03/05/8491792.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品99久久久久久动医院 | 久久国产精品系列 | 亚洲视频成人 | 欧美黑人性暴力猛交喷水黑人巨大 | 中文字幕在线不卡 | 久热中文 | 国产精品久久久久久久久久久久久 | 国产a自拍 | 另类国产ts人妖高潮系列视频 | 国产色视频在线观看免费 | 国产精品2区 | 亚洲综合色自拍一区 | 亚洲国产精品99久久久久久久久 | 亚洲福利一区 | 极品美女销魂一区二区三区 | 91九色在线 | 91黄视频| 成人影院在线观看 | www.亚色网.com| a毛片视频网站 | 中文字幕亚洲一区 | 欧美www| 精品国产91 | 日韩欧美~中文字幕 | 一区二区中文字幕 | 99视频精品在线 | 国产一区a| 91久久精品国产91久久 | 国产精品久久久久久久久久东京 | 黄色片网站 | 久久国产精品久久久久久久久久 | 国产欧美精品一区二区色综合 | 欧美亚洲一区 | 欧美精品成人一区二区在线 | 黄视频在线观看免费 | 国产欧美高清在线观看 | 欧美一区二区久久 | 久久久国产精品 | 亚洲欧美在线观看 | 欧日韩在线视频 | 日本精品免费 |