spring security
spring security是一個能夠為基于spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在spring應用上下文中配置的bean,充分利用了spring ioc,di(控制反轉inversion of control ,di:dependency injection 依賴注入)和aop(面向切面編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重復代碼的工作。
下載:https://github.com/whyalwaysmea/Spring-Security
本文重點給大家介紹springsecurity實現圖形驗證碼功能,具體內容如下:
1.開發生成圖形驗證碼接口
-> 封裝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
|
public class imagecode { private bufferedimage image; // 圖片 private string code; // 驗證碼 private localdatetime expiretime; // 有效時間 public imagecode(bufferedimage image, string code, int expirein) { this .image = image; this .code = code; // 出入一個秒數,自動轉為時間,如過期時間為60s,這里的expirein就是60,轉換為當前時間上加上這個秒數 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; } } |
-> 寫一個controller用于生成圖片和校驗驗證碼
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
|
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); // 將隨機數存到session中 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_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, xl, 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(); // 60秒有效 return new imagecode(image, srand, 60 ); } /** * 生成隨機背景條紋 * @param fc * @param bc * @return */ 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); } } |
第一步:根據隨機數生成圖片
1
|
imagecode imagecode = createimagecode(request); |
第二步:將隨機數存到session中
1
|
sessionstrategy.setattribute( new servletwebrequest(request), session_key, imagecode); |
第三步:將生成的圖片寫到接口的響應中
1
|
imageio.write(imagecode.getimage(), “jpeg”, response.getoutputstream()); |
-> 在靜態頁面中加入圖片驗證碼的標簽
1
2
3
4
5
6
7
|
<tr> <td>圖形驗證碼:</td> <td> <input type= "text" name= "imagecode" > <img src= "/code/image" > </td> </tr> |
-> 將接口請求地址配進認證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@override protected void configure(httpsecurity http) throws exception { http.formlogin() .loginpage( "/authencation/require" ) .loginprocessingurl( "/authentication/form" ) .successhandler(imoocauthenticationsuccesshandler) .failurehandler(imoocauthenticationfailurehandler) .and() .authorizerequests() .antmatchers( "/authencation/require" , securitypropertis.getbrowserpropertis().getloginpage(), "/code/image" ).permitall() // 加入"/code/image"地址 .anyrequest() .authenticated() .and() .csrf().disable(); } |
->啟動服務器訪問靜態表單
如圖所示:
2.在認證流程中加入圖形驗證碼校驗
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
|
-> 寫一個filter進行攔截 public class validatecodefilter extends onceperrequestfilter{ private authenticationfailurehandler authenticationfailurehandler; private sessionstrategy sessionstrategy = new httpsessionsessionstrategy(); @override protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain) throws servletexception, ioexception { //如果訪問的是/authentication/form并且為post請求 if (stringutils.equals( "/authentication/form" , request.getrequesturi()) && stringutils.equals(request.getmethod(), "post" )) { try { // 驗證圖片驗證碼是否填寫正確 validate( new servletwebrequest(request)); } catch (validatecodeexception e) { // 拋出異常,并返回,不再訪問資源 authenticationfailurehandler.onauthenticationfailure(request, response, e); return ; } } // 通過,執行后面的filter 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( "驗證碼的值不能為空" ); } 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; } } |
-> 配置再configure中,生效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@override protected void configure(httpsecurity http) throws exception { // 聲明filter validatecodefilter validatecodefilter = new validatecodefilter(); // 配置驗證失敗執行的handler validatecodefilter.setauthenticationfailurehandler(imoocauthenticationfailurehandler); // 添加filter到認證流程 http.addfilterbefore(validatecodefilter, usernamepasswordauthenticationfilter. class ) .formlogin() .loginpage( "/authencation/require" ) .loginprocessingurl( "/authentication/form" ) .successhandler(imoocauthenticationsuccesshandler) .failurehandler(imoocauthenticationfailurehandler) .and() .authorizerequests() .antmatchers( "/authencation/require" , securitypropertis.getbrowserpropertis().getloginpage(), "/code/image" ).permitall() .anyrequest() .authenticated() .and() .csrf().disable(); } |
至此,圖片驗證碼驗證流程已經全部完成。
啟動服務,進行測試即可。
總結
到此這篇關于SpringSecurity實現圖形驗證碼功能的實例代碼的文章就介紹到這了,更多相關SpringSecurity圖形驗證碼內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_43090405/article/details/83383902