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

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

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

服務器之家 - 編程語言 - Java教程 - SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

2021-07-22 15:47迷彩的博客 Java教程

這篇文章主要介紹了SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

摘要:用spring-boot開發restful api非常的方便,在生產環境中,對發布的api增加授權保護是非常必要的。現在我們來看如何利用jwt技術為api增加授權保護,保證只有獲得授權的用戶才能夠訪問api。

一:開發一個簡單的api

在idea開發工具中新建一個maven工程,添加對應的依賴如下:

?
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
<dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter</artifactid>
  </dependency>
 
  <dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-test</artifactid>
   <scope>test</scope>
  </dependency>
 
  <dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-web</artifactid>
  </dependency>
 
  <!-- spring-data-jpa -->
  <dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-data-jpa</artifactid>
  </dependency>
 
  <!-- mysql -->
  <dependency>
   <groupid>mysql</groupid>
   <artifactid>mysql-connector-java</artifactid>
   <version>5.1.30</version>
  </dependency>
 
  <!-- spring-security 和 jwt -->
  <dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-security</artifactid>
  </dependency>
  <dependency>
   <groupid>io.jsonwebtoken</groupid>
   <artifactid>jjwt</artifactid>
   <version>0.7.0</version>
  </dependency>

新建一個usercontroller.java文件,在里面在中增加一個hello方法:

?
1
2
3
4
5
@requestmapping("/hello")
 @responsebody
 public string hello(){
  return "hello";
 }

這樣一個簡單的restful api就開發好了。

現在我們運行一下程序看看效果,執行jwtauthapplication.java類中的main方法:

等待程序啟動完成后,可以簡單的通過curl工具進行api的調用,如下圖:

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

至此,我們的接口就開發完成了。但是這個接口沒有任何授權防護,任何人都可以訪問,這樣是不安全的,下面我們開始加入授權機制。

二:增加用戶注冊功能

首先增加一個實體類user.java:

?
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
package boss.portal.entity;
 
import javax.persistence.*;
 
/**
 * @author zhaoxinguo on 2017/9/13.
 */
@entity
@table(name = "tb_user")
public class user {
 
 @id
 @generatedvalue
 private long id;
 private string username;
 private string password;
 
 public long getid() {
  return 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;
 }
}

然后增加一個repository類userrepository,可以讀取和保存用戶信息:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package boss.portal.repository;
 
import boss.portal.entity.user;
import org.springframework.data.jpa.repository.jparepository;
 
/**
 * @author zhaoxinguo on 2017/9/13.
 */
public interface userrepository extends jparepository<user, long> {
 
 user findbyusername(string username);
 
}

在usercontroller類中增加注冊方法,實現用戶注冊的接口:

?
1
2
3
4
5
6
7
8
9
/**
  * 該方法是注冊用戶的方法,默認放開訪問控制
  * @param user
  */
 @postmapping("/signup")
 public void signup(@requestbody user user) {
  user.setpassword(bcryptpasswordencoder.encode(user.getpassword()));
  applicationuserrepository.save(user);
 }

其中的@postmapping("/signup")

這個方法定義了用戶注冊接口,并且指定了url地址是/users/signup。由于類上加了注解 @requestmapping(“/users”),類中的所有方法的url地址都會有/users前綴,所以在方法上只需指定/signup子路徑即可。

密碼采用了bcryptpasswordencoder進行加密,我們在application中增加bcryptpasswordencoder實例的定義。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package boss.portal;
 
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.context.annotation.bean;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
 
@springbootapplication
public class jwtauthapplication {
 
    @bean
    public bcryptpasswordencoder bcryptpasswordencoder() {
        return new bcryptpasswordencoder();
    }
 
    public static void main(string[] args) {
        springapplication.run(jwtauthapplication.class, args);
    }
}

三:增加jwt認證功能

用戶填入用戶名密碼后,與數據庫里存儲的用戶信息進行比對,如果通過,則認證成功。傳統的方法是在認證通過后,創建sesstion,并給客戶端返回cookie。現在我們采用jwt來處理用戶名密碼的認證。區別在于,認證通過后,服務器生成一個token,將token返回給客戶端,客戶端以后的所有請求都需要在http頭中指定該token。服務器接收的請求后,會對token的合法性進行驗證。驗證的內容包括:

  1. 內容是一個正確的jwt格式
  2. 檢查簽名
  3. 檢查claims
  4. 檢查權限

處理登錄

創建一個類jwtloginfilter,核心功能是在驗證用戶名密碼正確后,生成一個token,并將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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package boss.portal.web.filter;
import boss.portal.entity.user;
import com.fasterxml.jackson.databind.objectmapper;
import io.jsonwebtoken.jwts;
import io.jsonwebtoken.signaturealgorithm;
import org.springframework.security.authentication.authenticationmanager;
import org.springframework.security.authentication.usernamepasswordauthenticationtoken;
import org.springframework.security.core.authentication;
import org.springframework.security.core.authenticationexception;
import org.springframework.security.web.authentication.usernamepasswordauthenticationfilter;
 
import javax.servlet.filterchain;
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
import java.util.arraylist;
import java.util.date;
 
/**
 * 驗證用戶名密碼正確后,生成一個token,并將token返回給客戶端
 * 該類繼承自usernamepasswordauthenticationfilter,重寫了其中的2個方法
 * attemptauthentication :接收并解析用戶憑證。
 * successfulauthentication :用戶成功登錄后,這個方法會被調用,我們在這個方法里生成token。
 * @author zhaoxinguo on 2017/9/12.
 */
public class jwtloginfilter extends usernamepasswordauthenticationfilter {
 
 private authenticationmanager authenticationmanager;
 
 public jwtloginfilter(authenticationmanager authenticationmanager) {
  this.authenticationmanager = authenticationmanager;
 }
 
 // 接收并解析用戶憑證
 @override
 public authentication attemptauthentication(httpservletrequest req,
            httpservletresponse res) throws authenticationexception {
  try {
   user user = new objectmapper()
     .readvalue(req.getinputstream(), user.class);
 
   return authenticationmanager.authenticate(
     new usernamepasswordauthenticationtoken(
       user.getusername(),
       user.getpassword(),
       new arraylist<>())
   );
  } catch (ioexception e) {
   throw new runtimeexception(e);
  }
 }
 
 // 用戶成功登錄后,這個方法會被調用,我們在這個方法里生成token
 @override
 protected void successfulauthentication(httpservletrequest req,
           httpservletresponse res,
           filterchain chain,
           authentication auth) throws ioexception, servletexception {
 
  string token = jwts.builder()
    .setsubject(((org.springframework.security.core.userdetails.user) auth.getprincipal()).getusername())
    .setexpiration(new date(system.currenttimemillis() + 60 * 60 * 24 * 1000))
    .signwith(signaturealgorithm.hs512, "myjwtsecret")
    .compact();
  res.addheader("authorization", "bearer " + token);
 }
}

該類繼承自usernamepasswordauthenticationfilter,重寫了其中的2個方法:

attemptauthentication :接收并解析用戶憑證。

successfulauthentication :用戶成功登錄后,這個方法會被調用,我們在這個方法里生成token。

授權驗證

用戶一旦登錄成功后,會拿到token,后續的請求都會帶著這個token,服務端會驗證token的合法性。

創建jwtauthenticationfilter類,我們在這個類中實現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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package boss.portal.web.filter;
import io.jsonwebtoken.jwts;
import org.springframework.security.authentication.authenticationmanager;
import org.springframework.security.authentication.usernamepasswordauthenticationtoken;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.security.web.authentication.www.basicauthenticationfilter;
 
import javax.servlet.filterchain;
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
import java.util.arraylist;
 
/**
 * token的校驗
 * 該類繼承自basicauthenticationfilter,在dofilterinternal方法中,
 * 從http頭的authorization 項讀取token數據,然后用jwts包提供的方法校驗token的合法性。
 * 如果校驗通過,就認為這是一個取得授權的合法請求
 * @author zhaoxinguo on 2017/9/13.
 */
public class jwtauthenticationfilter extends basicauthenticationfilter {
 
 public jwtauthenticationfilter(authenticationmanager authenticationmanager) {
  super(authenticationmanager);
 }
 
 @override
 protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain chain) throws ioexception, servletexception {
  string header = request.getheader("authorization");
 
  if (header == null || !header.startswith("bearer ")) {
   chain.dofilter(request, response);
   return;
  }
 
  usernamepasswordauthenticationtoken authentication = getauthentication(request);
 
  securitycontextholder.getcontext().setauthentication(authentication);
  chain.dofilter(request, response);
 
 }
 
 private usernamepasswordauthenticationtoken getauthentication(httpservletrequest request) {
  string token = request.getheader("authorization");
  if (token != null) {
   // parse the token.
   string user = jwts.parser()
     .setsigningkey("myjwtsecret")
     .parseclaimsjws(token.replace("bearer ", ""))
     .getbody()
     .getsubject();
 
   if (user != null) {
    return new usernamepasswordauthenticationtoken(user, null, new arraylist<>());
   }
   return null;
  }
  return null;
 }
}

該類繼承自basicauthenticationfilter,在dofilterinternal方法中,從http頭的authorization 項讀取token數據,然后用jwts包提供的方法校驗token的合法性。如果校驗通過,就認為這是一個取得授權的合法請求。

springsecurity配置

通過springsecurity的配置,將上面的方法組合在一起。

?
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
package boss.portal.security;
import boss.portal.web.filter.jwtloginfilter;
import boss.portal.web.filter.jwtauthenticationfilter;
import org.springframework.boot.autoconfigure.security.securityproperties;
import org.springframework.context.annotation.configuration;
import org.springframework.core.annotation.order;
import org.springframework.http.httpmethod;
import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder;
import org.springframework.security.config.annotation.web.builders.httpsecurity;
import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter;
import org.springframework.security.core.userdetails.userdetailsservice;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
 
/**
 * springsecurity的配置
 * 通過springsecurity的配置,將jwtloginfilter,jwtauthenticationfilter組合在一起
 * @author zhaoxinguo on 2017/9/13.
 */
@configuration
@order(securityproperties.access_override_order)
public class websecurityconfig extends websecurityconfigureradapter {
 
 private userdetailsservice userdetailsservice;
 
 private bcryptpasswordencoder bcryptpasswordencoder;
 
 public websecurityconfig(userdetailsservice userdetailsservice, bcryptpasswordencoder bcryptpasswordencoder) {
  this.userdetailsservice = userdetailsservice;
  this.bcryptpasswordencoder = bcryptpasswordencoder;
 }
 
 @override
 protected void configure(httpsecurity http) throws exception {
  http.cors().and().csrf().disable().authorizerequests()
    .antmatchers(httpmethod.post, "/users/signup").permitall()
    .anyrequest().authenticated()
    .and()
    .addfilter(new jwtloginfilter(authenticationmanager()))
    .addfilter(new jwtauthenticationfilter(authenticationmanager()));
 }
 
 @override
 public void configure(authenticationmanagerbuilder auth) throws exception {
  auth.userdetailsservice(userdetailsservice).passwordencoder(bcryptpasswordencoder);
 }
 
}

這是標準的springsecurity配置內容,就不在詳細說明。注意其中的

?
1
2
.addfilter(new jwtloginfilter(authenticationmanager()))
.addfilter(new jwtauthenticationfilter(authenticationmanager()))

這兩行,將我們定義的jwt方法加入springsecurity的處理流程中。

下面對我們的程序進行簡單的驗證:

# 請求hello接口,會收到403錯誤,如下圖:

curl http://localhost:8080/hello

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

# 注冊一個新用戶curl -h"content-type: application/json" -x post -d '{"username":"admin","password":"password"}' http://localhost:8080/users/signup

如下圖:

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

# 登錄,會返回token,在http header中,authorization: bearer 后面的部分就是tokencurl -i -h"content-type: application/json" -x post -d '{"username":"admin","password":"password"}' http://localhost:8080/login

如下圖:

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

# 用登錄成功后拿到的token再次請求hello接口# 將請求中的xxxxxx替換成拿到的token# 這次可以成功調用接口了curl -h"content-type: application/json" \-h"authorization: bearer xxxxxx" \"http://localhost:8080/users/hello"

如下圖:

SpringBoot+Spring Security+JWT實現RESTful Api權限控制的方法

五:總結

至此,給springboot的接口加上jwt認證的功能就實現了,過程并不復雜,主要是開發兩個springsecurity的filter,來生成和校驗jwt token。

jwt作為一個無狀態的授權校驗技術,非常適合于分布式系統架構,因為服務端不需要保存用戶狀態,因此就無需采用redis等技術,在各個服務節點之間共享session數據。

六:源碼下載地址

地址:https://gitee.com/micai/springboot-springsecurity-jwt-demo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/sxdtzhaoxinguo/article/details/77965226

延伸 · 閱讀

精彩推薦
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
主站蜘蛛池模板: 亚洲成人三级 | 国产精品爱久久久久久久 | 精品国产乱码久久久久久丨区2区 | 美女h视频| 欧美综合成人网 | 中文字幕在线免费 | 欧美一区二区最爽乱淫视频免费看 | 国产精品一区二区三区免费 | 久久先锋 | 国产精品久久久久久亚洲调教 | www.天天操 | 一级黄免费看 | 懂色中文一区二区在线播放 | 综合精品 | 日韩av在线中文字幕 | 欧美日韩一区二区三区在线观看 | 国产精品一区二区不卡 | 国产极品探花 | 一区二区三区在线播放 | 免费视频一区二区 | 欧美va视频 | 日韩av电影在线观看 | 国产精品永久久久久久久久久 | 国产精品亲子伦av一区二区三区 | 国产一级视频在线观看 | 亚洲视频在线看 | 午夜小视频在线观看 | 欧美激情一区二区三区在线视频 | 国产午夜精品久久久久久久 | 国产一区二区三区在线观看免费 | 日韩欧美国产一区二区 | 午夜欧美一区二区三区在线播放 | 一区二区在线影院 | 91精品国产91久久久久久吃药 | 久久久久久久久久久精 | 日本高清视频在线播放 | 国产激情在线视频 | 国产一区二区免费视频 | 国产免费av网站 | 天天插天天狠 | 人人干天天干 |