一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

2020-09-07 09:11嗡湯圓 Java教程

本篇文章主要介紹了Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

最終效果

1、實(shí)現(xiàn)頁面訪問權(quán)限限制
2、用戶角色區(qū)分,并按照角色區(qū)分頁面權(quán)限
3、實(shí)現(xiàn)在數(shù)據(jù)庫中存儲(chǔ)用戶信息以及角色信息
4、自定義驗(yàn)證代碼

效果如下:

1、免驗(yàn)證頁面

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

2、登陸頁面

在用戶未登錄時(shí),訪問任意有權(quán)限要求的頁面都會(huì)自動(dòng)跳轉(zhuǎn)到登陸頁面。

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

3、需登陸才能查看的頁面

用戶登陸后,可以正常訪問頁面資源,同時(shí)可以正確顯示用戶登錄名:

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

4、用戶有角色區(qū)分,可以指定部分頁面只允許有相應(yīng)用戶角色的人使用

4.1、只有admin覺得用戶才能查看的頁面(權(quán)限不足)

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

4.2、只有admin覺得用戶才能查看的頁面(權(quán)限滿足)

Spring Boot中整合Spring Security并自定義驗(yàn)證代碼實(shí)例

以下具體說明實(shí)現(xiàn)步驟。

代碼實(shí)現(xiàn)

maven引入依賴

在pom.xml中引入spring security依賴

?
1
2
3
4
<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-security</artifactid>
</dependency>

配置spring security

在spring中,配置和使用spring security,在不需要修改太多流程細(xì)節(jié)的情況下僅需聲明好攔截規(guī)則,同時(shí)自定義驗(yàn)證過程中的主要實(shí)現(xiàn)接口(用戶信息userdetails,用戶信息獲取服務(wù)userdetailsservice,驗(yàn)證工具authenticationprovider)即可。其余的流程將由spring自動(dòng)接管,非常方便。

啟動(dòng)配置

在項(xiàng)目包下添加websecurityconfigureradapter 的具體實(shí)現(xiàn)類,實(shí)現(xiàn)spring security的啟動(dòng)配置

代碼如下:

?
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
@configurable
@enablewebsecurity
@enableglobalmethodsecurity(prepostenabled = true)//允許進(jìn)入頁面方法前檢驗(yàn)
public class websecurityconfig extends websecurityconfigureradapter {
 
  @autowired
  private myauthenticationprovider provider;//自定義驗(yàn)證
  @autowired
  private userdetailsservice userdetailsservice;//自定義用戶服務(wù)
  @autowired
  public void configauthentication(authenticationmanagerbuilder auth) throws exception{
  }
 
 
  @override
  protected void configure(httpsecurity http) throws exception {
    http.authorizerequests()
 
    .antmatchers(staticparams.pathregx.noauth,
        staticparams.pathregx.css,staticparams.pathregx.js,staticparams.pathregx.img).permitall()//無需訪問權(quán)限
 
    .antmatchers(staticparams.pathregx.authadmin).hasauthority(staticparams.userrole.role_admin)//admin角色訪問權(quán)限
 
    .antmatchers(staticparams.pathregx.authuser).hasauthority(staticparams.userrole.role_user)//user角色訪問權(quán)限
 
    .anyrequest()//all others request authentication
    .authenticated()
    .and()
    .formlogin().loginpage("/login").permitall()
    .and()
    .logout().permitall();
  }
 
  @autowired
  public void configureglobal(authenticationmanagerbuilder auth) throws exception {
    //將驗(yàn)證過程交給自定義驗(yàn)證工具
    auth.authenticationprovider(provider);
  }

url攔截配置

url攔截配置可以在上一小節(jié)的websecurityconfig 中配置,但是此方法適用于大方向上的配置,具體的特殊路徑也可以在@controller的注解中具體配置。

如下:

?
1
2
3
4
5
6
@responsebody
@preauthorize("hasauthority('"+staticparams.userrole.role_admin+"')")//這里可以指定特定角色的用戶訪問權(quán)限
@requestmapping(value = "adminrequire", method = requestmethod.get)
public string adminrequire(){
  return "hello from web but you should be admin";
}

用戶、角色表

在本文例子中用戶和角色可以有一對(duì)多的關(guān)系因此可以將用戶和角色分成兩張表。有些例子將用戶和權(quán)限寫在同一張表上也是可以的。

?
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
/*用戶表*/
@entity
@table(name = "user")
public class systemuser {
 
  @id
  @column(name = "id")
  @generatedvalue(strategy = generationtype.auto)
  private long id;
 
  private string username;
  private string password;
 
  public systemuser(){}
 
  public systemuser(systemuser user){
    this.username = user.getusername();
    this.password = user.getpassword();
    this.id = user.getid();
  }
 
  public long getid() {
    return id;
  }
  public void setid(long id) {
    this.id = id;
  }
  public string getusername() {
    return username;
  }
  public void setusername(string username) {
    this.username = username;
  }
  public string getpassword() {
    return password;
  }
  public void setpassword(string password) {
    this.password = password;
  }
}
/*角色表*/
@entity
@table(name = "user_role")
public class userrole {
 
  @id
  @column(name = "id")
  @generatedvalue(strategy = generationtype.auto)
  private long id;
 
  private string role;
  private long userid;
  public long getid() {
    return id;
  }
  public void setid(long id) {
    this.id = id;
  }
  public string getrole() {
    return role;
  }
  public void setrole(string role) {
    this.role = role;
  }
  public long getuserid() {
    return userid;
  }
  public void setuserid(long userid) {
    this.userid = userid;
  }
}

自定義驗(yàn)證

在spring boot的spring security的教程中默認(rèn)的用戶名、密碼、權(quán)限是在代碼中指定的

?
1
2
3
4
5
6
@autowired
  public void configureglobal(authenticationmanagerbuilder auth) throws exception {
    auth
      .inmemoryauthentication()
        .withuser("user").password("password").roles("user");
  }

這顯然是不符合應(yīng)用需求的,所以我們需要提供自定義的authenticationprovider,并在上邊代碼中替換即可。在此之前,我們應(yīng)該重寫獲取用戶user和權(quán)限的方法。通過查詢相關(guān)資料和api,方法提供如下:

自定義userdetails

userdetails代表了spring security的用戶認(rèn)證實(shí)體,帶有用戶名、密碼、權(quán)限列表、過期特性等性質(zhì),可以自己聲明類實(shí)現(xiàn)userdetails接口,如果不想自己聲明,也可以用springsecurity的默認(rèn)實(shí)現(xiàn)org.springframework.security.core.userdetails.user 本文例子中采用自定義類:

?
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
public class myuserdetails extends systemuser implements userdetails{
 
  private list<userrole> roles;
 
  public myuserdetails(systemuser user, list<userrole> roles){
    super(user);
    this.roles = roles;
  }
 
  @override
  public collection<? extends grantedauthority> getauthorities() {
    if(roles == null || roles.size() <1){
      return authorityutils.commaseparatedstringtoauthoritylist("");
    }
    stringbuilder commabuilder = new stringbuilder();
    for(userrole role : roles){
      commabuilder.append(role.getrole()).append(",");
    }
    string authorities = commabuilder.substring(0,commabuilder.length()-1);
    return authorityutils.commaseparatedstringtoauthoritylist(authorities);
  }
 
  @override
  public string getpassword() {
    return super.getpassword();
  }
 
  @override
  public string getusername() {
    return super.getusername();
  }
 
  @override
  public boolean isaccountnonexpired() {
    return true;
  }
 
  @override
  public boolean isaccountnonlocked() {
    return true;
  }
 
  @override
  public boolean iscredentialsnonexpired() {
    return true;
  }
 
  @override
  public boolean isenabled() {
    return true;
  }
 
}

自定義userdetailsservice

userdetailsservice提供了獲取userdetails的方式,只要實(shí)現(xiàn)userdetailsservice接口即可,最終生成用戶和權(quán)限共同組成的userdetails,在這里就可以實(shí)現(xiàn)從自定義的數(shù)據(jù)源中獲取用戶信息了:

?
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
@service("myuserdetailsimpl")
public class myuserdetailsservice implements userdetailsservice {
  @resource(name = "systemuserserviceimpl")
  private systemuserservice systemuserservice;
 
  @resource(name = "userroleserviceimpl")
  private userroleservice userroleservice;
 
  @override
  public userdetails loaduserbyusername(string username) throws usernamenotfoundexception {
    systemuser user;
    try {
      user = systemuserservice.findbyname(username);
    } catch (exception e) {
      throw new usernamenotfoundexception("user select fail");
    }
    if(user == null){
      throw new usernamenotfoundexception("no user found");
    } else {
      try {
        list<userrole> roles = userroleservice.getrolebyuser(user);
        return new myuserdetails(user, roles);
      } catch (exception e) {
        throw new usernamenotfoundexception("user role select fail");
      }
    }
  }
}

自定義authenticationprovider

authenticationprovider 提供用戶userdetails的具體驗(yàn)證方式,在這里可以自定義用戶密碼的加密、驗(yàn)證方式等等。因?yàn)椴┪闹饕v的是如何引入spring security和如何自定義驗(yàn)證代碼,所以這里為了簡(jiǎn)便,我直接采用明文比較方式:

?
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
@component
public class myauthenticationprovider implements authenticationprovider {
 
  @autowired
  private myuserdetailsservice userservice;
 
  /**
   * 自定義驗(yàn)證方式
   */
  @override
  public authentication authenticate(authentication authentication) throws authenticationexception {
    string username = authentication.getname();
    string password = (string) authentication.getcredentials();
    myuserdetails user = (myuserdetails) userservice.loaduserbyusername(username);
    if(user == null){
      throw new badcredentialsexception("username not found.");
    }
 
    //加密過程在這里體現(xiàn)
    if (!password.equals(user.getpassword())) {
      throw new badcredentialsexception("wrong password.");
    }
 
    collection<? extends grantedauthority> authorities = user.getauthorities();
    return new usernamepasswordauthenticationtoken(user, password, authorities);
  }
 
  @override
  public boolean supports(class<?> arg0) {
    return true;
  }
 
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://blog.csdn.net/tzdwsy/article/details/50738043

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久九九精品免费视频 | 香港日本三级亚洲三级 | 校花的第一次好紧好爽 | 日本无卡码一区二区三区 | 亚洲精品视频久久 | 91在线永久| 国产亚洲精aa在线观看香蕉 | 末代皇帝无删减版在线观看 | 厨房play黄瓜进入 | 午夜影院免费观看视频 | 青青草伊人久久 | free chinese麻豆 | 国产精品毛片高清在线完整版 | 国产成人久久精品一区二区三区 | 398av影院视频在线 | 日本动漫打扑克动画片樱花动漫 | 啊啊啊好大好爽视频 | 99色在线视频 | 免费国产一级观看完整版 | 国产午夜久久精品 | 免费观看国产精品 | 午夜精品久久久久久 | 亚洲精品国产精品麻豆99 | 色综合合久久天天综合绕视看 | 亚洲国产区中文在线观看 | 日韩性公交车上xxhd免费 | 妇乱子伦激情 | 国产ay | 苍井空50分钟无码 | 女子监狱第二季未删减在线看 | 色啪久久婷婷综合激情 | 亚洲精品二三区伊人久久 | 美女扒开奶罩让男人吃奶 | 色哟哟精品 | 精品亚洲欧美中文字幕在线看 | 国产福利在线免费观看 | 国产一区二区三区高清视频 | 国产欧美国产精品第一区 | 亚洲 欧美 国产 日韩 字幕 | 11 13加污女qq看他下面 | 99久久精品自在自看国产 |