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

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

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

服務器之家 - 編程語言 - Java教程 - spring security自定義認證登錄的全過程記錄

spring security自定義認證登錄的全過程記錄

2021-03-09 14:19CatalpaFlat Java教程

這篇文章主要給大家介紹了關于spring security自定義認證登錄的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

spring security使用分類:

如何使用spring security,相信百度過的都知道,總共有四種用法,從簡到深為:

1、不用數據庫,全部數據寫在配置文件,這個也是官方文檔里面的demo;

2、使用數據庫,根據spring security默認實現代碼設計數據庫,也就是說數據庫已經固定了,這種方法不靈活,而且那個數據庫設計得很簡陋,實用性差;

3、spring security和acegi不同,它不能修改默認filter了,但支持插入filter,所以根據這個,我們可以插入自己的filter來靈活使用;

4、暴力手段,修改源碼,前面說的修改默認filter只是修改配置文件以替換filter而已,這種是直接改了里面的源碼,但是這種不符合oo設計原則,而且不實際,不可用。

本文主要介紹了關于spring security自定義認證登錄的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

1.概要

1.1.簡介

spring security是一種基于 spring aop 和 servlet 過濾器的安全框架,以此來管理權限認證等。

1.2.spring security 自定義認證流程

1)認證過程

生成未認證的authenticationtoken                 

?
1
2
3
4
5
6
7
8
↑(獲取信息)  (根據authenticationtoken分配provider)    
authenticationfilter -> authenticationmanager -> authenticationprovider
       ↓(認證)
      userdetails(一般查詢數據庫獲取)
       ↓(通過)
       生成認證成功的authenticationtoken
        ↓(存放)
       securitycontextholder

2)將authenticationfilter加入到security過濾鏈(資源服務器中配置),如:

?
1
http.addfilterbefore(authenticationfilter, abstractpreauthenticatedprocessingfilter.class)

或者:

?
1
http.addfilterafter(authenticationfilter, usernamepasswordauthenticationfilter.class)

2.以手機號短信登錄為例

2.1.開發環境

  • springboot
  • spring security
  • redis

2.2.核心代碼分析

2.2.1.自定義登錄認證流程

2.2.1.1.自定義認證登錄token

?
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
/**
 * 手機登錄token
 *
 * @author : catalpaflat
 */
public class mobileloginauthenticationtoken extends abstractauthenticationtoken {
 private static final long serialversionuid = springsecuritycoreversion.serial_version_uid;
 private static final logger logger = loggerfactory.getlogger(mobileloginauthenticationtoken.class.getname());
 private final object principal;
 public mobileloginauthenticationtoken(string mobile) {
 super(null);
 this.principal = mobile;
 this.setauthenticated(false);
 logger.info("mobileloginauthenticationtoken setauthenticated ->false loading ...");
 }
 public mobileloginauthenticationtoken(object principal,
      collection<? extends grantedauthority> authorities) {
 super(authorities);
 this.principal = principal;
 // must use super, as we override
 super.setauthenticated(true);
 logger.info("mobileloginauthenticationtoken setauthenticated ->true loading ...");
 }
 @override
 public void setauthenticated(boolean authenticated) {
 if (authenticated) {
  throw new illegalargumentexception(
   "cannot set this token to trusted - use constructor which takes a grantedauthority list instead");
 }
 super.setauthenticated(false);
 }
 @override
 public object getcredentials() {
 return null;
 }
 @override
 public object getprincipal() {
 return this.principal;
 }
 @override
 public void erasecredentials() {
 super.erasecredentials();
 }
}

注:

setauthenticated():判斷是否已認證

  • 在過濾器時,會生成一個未認證的authenticationtoken,此時調用的是自定義token的setauthenticated(),此時設置為false -> 未認證
  • 在提供者時,會生成一個已認證的authenticationtoken,此時調用的是父類的setauthenticated(),此時設置為true -> 已認證

2.2.1.1.自定義認證登錄過濾器

?
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
/**
 * 手機短信登錄過濾器
 *
 * @author : catalpaflat
 */
public class mobileloginauthenticationfilter extends abstractauthenticationprocessingfilter {
 private boolean postonly = true;
 private static final logger logger = loggerfactory.getlogger(mobileloginauthenticationfilter.class.getname());
 @getter
 @setter
 private string mobileparametername;
 public mobileloginauthenticationfilter(string mobileloginurl, string mobileparametername,
      string httpmethod) {
 super(new antpathrequestmatcher(mobileloginurl, httpmethod));
 this.mobileparametername = mobileparametername;
 logger.info("mobileloginauthenticationfilter loading ...");
 }
 @override
 public authentication attemptauthentication(httpservletrequest request,      httpservletresponse response) throws authenticationexception, ioexception, servletexception {
 if (postonly && !request.getmethod().equals(httpmethod.post.name())) {
  throw new authenticationserviceexception("authentication method not supported: " + request.getmethod());
 }
 //get mobile
 string mobile = obtainmobile(request);
 //assemble token
 mobileloginauthenticationtoken authrequest = new mobileloginauthenticationtoken(mobile);
 
 // allow subclasses to set the "details" property
 setdetails(request, authrequest);
 
 return this.getauthenticationmanager().authenticate(authrequest);
 }
 /**
 * 設置身份認證的詳情信息
 */
 private void setdetails(httpservletrequest request, mobileloginauthenticationtoken authrequest) {
 authrequest.setdetails(authenticationdetailssource.builddetails(request));
 }
 /**
 * 獲取手機號
 */
 private string obtainmobile(httpservletrequest request) {
 return request.getparameter(mobileparametername);
 }
 public void setpostonly(boolean postonly) {
 this.postonly = postonly;
 }
}

注:attemptauthentication()方法:

  • 過濾指定的url、httpmethod
  • 獲取所需請求參數數據封裝生成一個未認證的authenticationtoken
  • 傳遞給authenticationmanager認證

2.2.1.1.自定義認證登錄提供者

?
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
/**
 * 手機短信登錄認證提供者
 *
 * @author : catalpaflat
 */
public class mobileloginauthenticationprovider implements authenticationprovider {
 private static final logger logger = loggerfactory.getlogger(mobileloginauthenticationprovider.class.getname());
 @getter
 @setter
 private userdetailsservice customuserdetailsservice;
 public mobileloginauthenticationprovider() {
 logger.info("mobileloginauthenticationprovider loading ...");
 }
 /**
 * 認證
 */
 @override
 public authentication authenticate(authentication authentication) throws authenticationexception {
 //獲取過濾器封裝的token信息
 mobileloginauthenticationtoken authenticationtoken = (mobileloginauthenticationtoken) authentication;
 //獲取用戶信息(數據庫認證)
 userdetails userdetails = customuserdetailsservice.loaduserbyusername((string) authenticationtoken.getprincipal());
 //不通過
 if (userdetails == null) {
  throw new internalauthenticationserviceexception("unable to obtain user information");
 }
 //通過
 mobileloginauthenticationtoken authenticationresult = new mobileloginauthenticationtoken(userdetails, userdetails.getauthorities());
 authenticationresult.setdetails(authenticationtoken.getdetails());
 
 return authenticationresult;
 }
 /**
 * 根據token類型,來判斷使用哪個provider
 */
 @override
 public boolean supports(class<?> authentication) {
 return mobileloginauthenticationtoken.class.isassignablefrom(authentication);
 }
}

注:authenticate()方法

  • 獲取過濾器封裝的token信息
  • 調取userdetailsservice獲取用戶信息(數據庫認證)->判斷通過與否
  • 通過則封裝一個新的authenticationtoken,并返回

2.2.1.1.自定義認證登錄認證配置

?
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
@configuration(springbeannameconstant.default_custom_mobile_login_authentication_security_config_bn)
public class mobileloginauthenticationsecurityconfig extends securityconfigureradapter<defaultsecurityfilterchain, httpsecurity> {
 private static final logger logger = loggerfactory.getlogger(mobileloginauthenticationsecurityconfig.class.getname());
 @value("${login.mobile.url}")
 private string defaultmobileloginurl;
 @value("${login.mobile.parameter}")
 private string defaultmobileloginparameter;
 @value("${login.mobile.httpmethod}")
 private string defaultmobileloginhttpmethod;
 @autowired
 private customymlconfig customymlconfig;
 @autowired
 private userdetailsservice customuserdetailsservice;
 @autowired
 private authenticationsuccesshandler customauthenticationsuccesshandler;
 @autowired
 private authenticationfailurehandler customauthenticationfailurehandler;
 public mobileloginauthenticationsecurityconfig() {
 logger.info("mobileloginauthenticationsecurityconfig loading ...");
 }
 @override
 public void configure(httpsecurity http) throws exception {
 mobilepojo mobile = customymlconfig.getlogins().getmobile();
 string url = mobile.geturl();
 string parameter = mobile.getparameter().getmobile();
 string httpmethod = mobile.gethttpmethod();
 mobileloginauthenticationfilter mobileloginauthenticationfilter = new mobileloginauthenticationfilter(stringutils.isblank(url) ? defaultmobileloginurl : url,
  stringutils.isblank(parameter) ? defaultmobileloginurl : parameter, stringutils.isblank(httpmethod) ? defaultmobileloginhttpmethod : httpmethod); mobileloginauthenticationfilter.setauthenticationmanager(http.getsharedobject(authenticationmanager.class)); mobileloginauthenticationfilter.setauthenticationsuccesshandler(customauthenticationsuccesshandler); mobileloginauthenticationfilter.setauthenticationfailurehandler(customauthenticationfailurehandler);
 mobileloginauthenticationprovider mobileloginauthenticationprovider = new mobileloginauthenticationprovider(); mobileloginauthenticationprovider.setcustomuserdetailsservice(customuserdetailsservice);
 http.authenticationprovider(mobileloginauthenticationprovider)
  .addfilterafter(mobileloginauthenticationfilter, usernamepasswordauthenticationfilter.class);
 }
}

注:configure()方法

實例化authenticationfilter和authenticationprovider

將authenticationfilter和authenticationprovider添加到spring security中。

2.2.2.基于redis自定義驗證碼校驗

2.2.2.1.基于redis自定義驗證碼過濾器

?
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
/**
 * 驗證碼過濾器
 *
 * @author : catalpaflat
 */
@component(springbeannameconstant.default_validate_code_filter_bn)
public class validatecodefilter extends onceperrequestfilter implements initializingbean {
 private static final logger logger = loggerfactory.getlogger(validatecodefilter.class.getname());
 @autowired
 private customymlconfig customymlconfig;
 @autowired
 private redistemplate<object, object> redistemplate;
 /**
  * 驗證請求url與配置的url是否匹配的工具類
  */
 private antpathmatcher pathmatcher = new antpathmatcher();
 public validatecodefilter() {
  logger.info("loading validatecodefilter...");
 }
 @override
 protected void dofilterinternal(httpservletrequest request, httpservletresponse response,
         filterchain filterchain) throws servletexception, ioexception {
  string url = customymlconfig.getlogins().getmobile().geturl();
  if (pathmatcher.match(url, request.getrequesturi())) {
   string deviceid = request.getheader("deviceid");
   if (stringutils.isblank(deviceid)) {
    throw new customexception(httpstatus.not_acceptable.value(), "not deviceid in the head of the request");
   }
   string codeparamname = customymlconfig.getlogins().getmobile().getparameter().getcode();
   string code = request.getparameter(codeparamname);
   if (stringutils.isblank(code)) {
    throw new customexception(httpstatus.not_acceptable.value(), "not code in the parameters of the request");
   }
   string key = systemconstant.default_mobile_key_pix + deviceid;
   smscodepo smscodepo = (smscodepo) redistemplate.opsforvalue().get(key);
   if (smscodepo.isexpried()){
    throw new customexception(httpstatus.bad_request.value(), "the verification code has expired");
   }
   string smscode = smscodepo.getcode();
   if (stringutils.isblank(smscode)) {
    throw new customexception(httpstatus.bad_request.value(), "verification code does not exist");
   }
   if (stringutils.equals(code, smscode)) {
    redistemplate.delete(key);
    //let it go
    filterchain.dofilter(request, response);
   } else {
    throw new customexception(httpstatus.bad_request.value(), "validation code is incorrect");
   }
  }else {
   //let it go
   filterchain.dofilter(request, response);
  }
 }
}

注:dofilterinternal()

自定義驗證碼過濾校驗

2.2.2.2.將自定義驗證碼過濾器添加到spring security過濾器鏈

?
1
http.addfilterbefore(validatecodefilter, abstractpreauthenticatedprocessingfilter.class)

注:添加到認證預處理過濾器前

3.測試效果

spring security自定義認證登錄的全過程記錄

spring security自定義認證登錄的全過程記錄

spring security自定義認證登錄的全過程記錄

spring security自定義認證登錄的全過程記錄

最后附上源碼地址:https://gitee.com/catalpaflat/springsecurity.git  

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://juejin.im/post/5a3b7f5c6fb9a0452936ee2a

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩在线精品 | 欧美一区二区在线视频 | 久久久精品亚洲 | 国产精品一区久久 | 爱干视频 | 国产成人在线一区二区 | 伊人一区二区三区 | 懂色aⅴ精品一区二区三区蜜月 | 日韩超级大片免费看国产国产播放器 | 精品成人免费一区二区在线播放 | 国产欧美精品一区二区三区四区 | 四虎成人免费电影 | 成人av播放 | 日韩欧美一区二区在线观看视频 | 国产精品美女久久久久久久久久久 | 日韩欧美一区二区在线观看 | 伊人网在线 | 国产成人a亚洲精品 | 精品一区二区av | 日本福利网站 | 日韩一区电影 | 精品视频久久久 | 99精品久久久| 一区二区三区四区日韩 | 欧美日韩亚洲国产 | 欧美 日韩 国产 成人 在线 | 日韩中文字幕在线播放 | 国产在线视频网 | 中文字幕在线第一页 | 亚洲精品国产setv | 成人午夜性a一级毛片免费看 | 激情亚洲| 成人中文字幕在线观看 | 91av影院 | 日韩欧美精品在线 | 国产亚洲视频在线 | 亚洲精品在线播放 | 国产成人一区二区 | 日韩亚洲| 亚洲男性天堂 | 国产欧美精品一区 |