Spring Security + JWT學習


開胃:Oauth2認證流程分析

現在第三方登錄已經很普遍了,隨便哪個App都會有使用微信登錄,使用手機號碼登錄,或者使用支付寶登錄等功能...

下面我們就以使用微信登錄,做一個簡單的流程分析分析

開胃:JWT認識

在上面的Oauth2的認證流程中,我們就可以看出一些貓膩來:

  • 在我們拿着令牌去用戶信息系統調用用戶的相關信息的時候,

  • 用戶信息系統其實去請求了授權服務器,驗證l了該令牌的合法性

這樣每次認證都需要去調用授權服務器做一個令牌合法性驗證,顯得效率低下。

JWT令牌思想

JWT令牌場景運用

之前返回的令牌就是一個普通的令牌,使用了JWT之后,這個令牌彷佛變得有點意思了起來

  • 用戶在授權服務器通過之后,會得到一個JWT令牌;

  • 這個令牌中就已經包含了用戶相關的信息;

  • 客戶端只需要攜帶該JWT令牌訪問資源服務器即可;

  • 資源服務器會按照約定的算法自動完成令牌的校驗,這就就不用再去請求授權服務器了

流程我相信大家都已經看懂了,下面我們就來一點文的,解釋一下JWT

JWT簡單介紹

Json Web Token:JWT一共包含了三部分數據,這三部分數據通過.分割拼接而成的字符串,如:xxx.yyy.zzz

1.Header:頭部【JSON】,通常頭部有兩部份信息,我們可對頭部信息進行base64加密解密得到頭部信息

  • 聲明類型,這是一個JWT

  • 聲明加密算法:自定義(HMAC / RSA /...)

  • 如下所示模樣,

  • {
    "typ": "JWT",
    "alg": "HS256"
    }

2.payload【JSON】:載荷,就是我們要寄存的數據,一般包含一下信息

  • 用戶身份信息(采用bases加密,可解密,不建議存放過於敏感的信息)

  • 注冊聲明:如該token的簽發時間,過期時間(exp),簽發人(iss)等信息

  • 如下所示模樣:

  • {
    "name": "456",
    "admin": true
    }

3.Signature:簽名,是整個數據的認證信息,

一般根據前兩部的數據再加上服務器上的密鑰通過加密算法生成,用於驗證整個數據的完整性和可靠性

  • 如下所示模樣:

  • HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)
  • base64UrlEncode(header) :令牌的頭部分

  • base64UrlEncode(payload):令牌的載荷

  • secret :簽名所使用的密鑰

看到這里,腦子里一現,是不是可以實現單點登錄哦?就用載荷保存用戶的唯一id,其他服務豈不是就可以獲得用戶信息?

Spring Security + JWT的Demo

項目介紹

  • 這里或許你就會有疑問了?為什么上面我們說了Oauth2,這里卻不小試牛刀呢?

  • 因為 Oauth2一般運用與分布式項目中,需要單獨起一個服務做鑒權服務,而我並沒有想去搭建一套SpringCloud的想法

  • 所以這里就借着網上的一點小資料,代碼也是模仿的別人的,我對它進行吸收並做下學習筆記順便分享出來

pom文件指定相關依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ninja.study</groupId>
    <artifactId>security_demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Ninja-Security</name>
    <description>鞋破露腳尖兒</description><properties>
        <java.version>1.8</java.version>
    </properties><dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.7</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.7</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.7</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency><dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build></project>

application.yml配置

更正一下,mysql的驅動類后面更換為了:com.mysql.cj.jdbc.Driver 望周知!

Code:GitHub見

不好理解的地方做了特別詳細的說明,大家學習可自行下載即可:

GitHub

項目說明望周知

自測結果先說明一下:

注冊用戶

用戶登錄:

用戶帶着token去訪問服務

然后就是項目源碼說明:TODO 觀看大體上的說明即可,比較難理解的我都是一行一行給了備注的

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM