最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot+JWT實現(xiàn)單點登錄完美解決方案

 更新時間:2023年07月05日 09:41:39   作者:qinxun2008081  
單點登錄是一種統(tǒng)一認證和授權機制,指在多個應用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的系統(tǒng),不需要重新登錄驗證,這篇文章主要介紹了SpringBoot+JWT實現(xiàn)單點登錄解決方案,需要的朋友可以參考下

一、什么是單點登錄?

單點登錄是一種統(tǒng)一認證和授權機制,指在多個應用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的系統(tǒng),不需要重新登錄驗證。

單點登錄一般用于互相授信的系統(tǒng),實現(xiàn)單一位置登錄,其他信任的應用直接免登錄的方式,在多個應用系統(tǒng)中,只需要登錄一次,就可以訪問其他互相信任的應用系統(tǒng)。

隨著時代的演進,大型web系統(tǒng)早已從單體應用架構發(fā)展為如今的多系統(tǒng)分布式應用群。但無論系統(tǒng)內部多么復雜,對用戶而言,都是一個統(tǒng)一的整體,訪問web系統(tǒng)的整個應用群要和訪問單個系統(tǒng)一樣,登錄/注銷只要一次就夠了,不可能讓一個用戶在每個業(yè)務系統(tǒng)上都進行一次登錄驗證操作,這時就需要獨立出一個單獨的認證系統(tǒng),它就是單點登錄系統(tǒng)。

二、單點登錄的優(yōu)點

1.方便用戶使用。用戶不需要多次登錄系統(tǒng),不需要記住多個密碼,方便用戶操作。

2.提高開發(fā)效率。單點登錄為開發(fā)人員提供類一個通用的驗證框架。

3.簡化管理。如果在應用程序中加入了單點登錄的協(xié)議,管理用戶賬戶的負擔就會減輕。

三、JWT 機制

JWT(JSON Web Token)它將用戶信息加密到token里,服務器不保存任何用戶信息。服務器通過使用保存的密鑰驗證JWTToken的正確性,只要正確就通過驗證。

數(shù)據結構:

JWT包含三個部分:Header頭部,Payload負載和Signature簽名。三個部門用“.”分割。校驗也是JWT內部自己實現(xiàn)的 ,并且可以將你存儲時候的信息從token中取出來無須查庫。

JWT執(zhí)行流程:

JWT的請求流程也特別簡單,首先使用賬號登錄獲取Token,然后后面的各種請求,都帶上這個Token即可。具體流程如下:

1. 客戶端發(fā)起登錄請求,傳入賬號密碼;

2. 服務端使用私鑰創(chuàng)建一個Token;

3. 服務器返回Token給客戶端;

4. 客戶端向服務端發(fā)送請求,在請求頭中攜帶Token;

5. 服務器驗證該Token;

6. 返回結果。

四.創(chuàng)建Maven父項目

 2.指定打包類型為pom

 五.創(chuàng)建認證模塊sso

 1.添加依賴,完整的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.7.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sso</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sso</name>
    <description>sso</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.2</version>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-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>

2添加jwt相關配置

 3.創(chuàng)建JWT配置類和JWT工具類

示例代碼如下:

package com.example.sso.bean;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * @author qx
 * @date 2023/7/4
 * @des Jwt配置類
 */
@Component
@ConfigurationProperties(prefix = "jwt")
@Getter
@Setter
public class JwtProperties {
    /**
     * 過期時間-分鐘
     */
    private Integer expireTime;
    /**
     * 密鑰
     */
    private String secret;
}
package com.example.sso.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.sso.bean.JwtProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
 * @author qx
 * @date 2023/7/4
 * @des JWT工具類
 */
@Component
public class JwtUtil {
    @Autowired
    private JwtProperties jwtProperties;
    /**
     * 生成一個jwt字符串
     *
     * @param username 用戶名
     * @return jwt字符串
     */
    public String sign(String username) {
        Algorithm algorithm = Algorithm.HMAC256(jwtProperties.getSecret());
        return JWT.create()
                // 設置過期時間1個小時
                .withExpiresAt(new Date(System.currentTimeMillis() + jwtProperties.getExpireTime() * 60 * 1000))
                // 設置負載
                .withClaim("username", username).sign(algorithm);
    }
    public static void main(String[] args) {
        Algorithm algorithm = Algorithm.HMAC256("KU5TjMO6zmh03bU3");
        String username = "admin";
        String token = JWT.create()
                // 設置過期時間1個小時
                .withExpiresAt(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
                // 設置負載
                .withClaim("username", username).sign(algorithm);
        System.out.println(token);
    }
    /**
     * 校驗token是否正確
     *
     * @param token token值
     */
    public boolean verify(String token) {
        if (token == null || token.length() == 0) {
            throw new RuntimeException("token為空");
        }
        try {
            Algorithm algorithm = Algorithm.HMAC256(jwtProperties.getSecret());
            JWTVerifier jwtVerifier = JWT.require(algorithm).build();
            jwtVerifier.verify(token);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

4.創(chuàng)建服務層

package com.example.sso.service;
import com.example.sso.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author qx
 * @date 2023/7/4
 * @des 登錄服務層
 */
@Service
public class LoginService {
    @Autowired
    private JwtUtil jwtUtil;
    /**
     * 登錄
     *
     * @param username 用戶名
     * @param password 密碼
     * @return token值
     */
    public String login(String username, String password) {
        if ("".equals(username) || "".equals(password)) {
            throw new RuntimeException("用戶名或密碼不能為空");
        }
        // 為了測試方便 不去數(shù)據庫比較密碼
        if ("123".equals(password)) {
            // 返回生成的token
            return jwtUtil.sign(username);
        }
        return null;
    }
    /**
     * 校驗jwt是否成功
     *
     * @param token    token值
     * @return 校驗是否超過
     */
    public boolean checkJwt(String token) {
        return jwtUtil.verify(token);
    }
}

5.創(chuàng)建控制層

package com.example.sso.controller;
import com.example.sso.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * @author qx
 * @date 2023/7/4
 * @des 驗證控制層
 */
@Controller
@RequestMapping("/sso")
public class AuthController {
    @Autowired
    private LoginService loginService;
    /**
     * 登錄頁面
     */
    @GetMapping("/login")
    public String toLogin() {
        return "login";
    }
    /**
     * 登錄
     *
     * @param username 用戶名
     * @param password 密碼
     * @return token值
     */
    @PostMapping("/login")
    @ResponseBody
    public String login(String username, String password) {
        return loginService.login(username, password);
    }
    /**
     * 驗證jwt
     *
     * @param token token
     * @return 驗證jwt是否合法
     */
    @RequestMapping("/checkJwt")
    @ResponseBody
    public boolean checkJwt(String token) {
        return loginService.checkJwt(token);
    }
}

6.創(chuàng)建一個登錄頁面login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
    <form method="post" action="/sso/login">
        用戶名:<input type="text" name="username"/><br/>
        密碼:<input type="password" name="password"/><br/>
        <button type="submit">登錄</button>
    </form>
</body>
</html>

六、創(chuàng)建應用系統(tǒng)projectA 

 1.項目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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>my-sso</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>projectA</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.13</version>
        </dependency>
        <!--okhttp-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
        </dependency>
    </dependencies>
</project>

 2.修改配置文件

 3.創(chuàng)建過濾器

package com.example.projectA.filter;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author qx
 * @date 2023/7/4
 * @des 登錄過濾器
 */
@Component
@WebFilter(urlPatterns = "/**")
public class LoginFilter implements Filter {
    @Value("${sso_server}")
    private String serverHost;
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String token = httpServletRequest.getParameter("token");
        if (this.check(token)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            String redirect = serverHost + "/login";
            response.sendRedirect(redirect);
        }
    }
    /**
     * 驗證token
     *
     * @param token
     * @return
     * @throws IOException
     */
    private boolean check(String token) throws IOException {
        if (token == null || token.trim().length() == 0) {
            return false;
        }
        OkHttpClient client = new OkHttpClient();
        // 請求驗證token的合法性
        String url = serverHost + "/checkJwt?token=" + token;
        Request request = new Request.Builder().url(url).build();
        Response response = client.newCall(request).execute();
        return Boolean.parseBoolean(response.body().string());
    }
}

4.創(chuàng)建測試控制層

package com.example.projectA.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author qx
 * @date 2023/7/4
 * @des 測試A
 */
@RestController
public class IndexController {
    @GetMapping("/testA")
    public String testA() {
        return "輸出testA";
    }
}

5.啟動類

package com.example.projectA;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
 * @author qx
 * @date 2023/7/4
 * @des Projecta啟動類
 */
@SpringBootApplication
@ServletComponentScan
public class ProjectaApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProjectaApplication.class,args);
    }
}

6.啟動項目測試

我們訪問http://localhost:8081/testA 系統(tǒng)跳轉到了驗證模塊的登錄頁面

我們輸入賬號密碼登錄成功后返回token

 如何我們復制這段數(shù)據,把數(shù)據傳遞到token參數(shù)。

 我們看到正確獲取到了數(shù)據。

七、創(chuàng)建應用系統(tǒng)projectB

我們再次模仿projectA創(chuàng)建projectB子模塊。

 啟動模塊B

我們直接測試帶上token參數(shù)

通過之前的token,無需登錄即可成功進入了應用系統(tǒng)B。說明我們的單點登錄系統(tǒng)搭建成功。

到此這篇關于SpringBoot+JWT實現(xiàn)單點登錄解決方案的文章就介紹到這了,更多相關SpringBoot JWT單點登錄內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • IntelliJ IDEA彈出“IntelliJ IDEA License Activation”的處理方法

    IntelliJ IDEA彈出“IntelliJ IDEA License Activation”的處理方法

    這篇文章主要介紹了IntelliJ IDEA彈出“IntelliJ IDEA License Activation”的處理方法,本文給出解決方法,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    文章詳細介紹了SpringBoot中Get請求和POST請求的參數(shù)接收方式,包括方法形參接收參數(shù)、實體類接收參數(shù)、HttpServletRequest接收參數(shù)、@PathVariable接收參數(shù)、數(shù)組參數(shù)接收、集合參數(shù)接收、Map接收參數(shù)以及通過@RequestBody接收JSON格式的參數(shù),感興趣的朋友一起看看吧
    2024-12-12
  • java實現(xiàn)批量下載 多文件打包成zip格式下載

    java實現(xiàn)批量下載 多文件打包成zip格式下載

    這篇文章主要為大家詳細介紹了java實現(xiàn)批量下載、將多文件打包成zip格式下載,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java讀取Excel、docx、pdf和txt等文件萬能方法舉例

    Java讀取Excel、docx、pdf和txt等文件萬能方法舉例

    在Java開發(fā)中處理文件是常見需求,本文以實際代碼示例詳述如何使用ApachePOI庫及其他工具讀取和寫入Excel、Word、PDF等文件,介紹了ApachePOI、ApachePDFBox和EasyExcel等庫的使用方法,幫助開發(fā)者有效讀取不同格式文件,需要的朋友可以參考下
    2024-09-09
  • Java WindowBuilder 安裝及基本使用的教程

    Java WindowBuilder 安裝及基本使用的教程

    這篇文章主要介紹了Java WindowBuilder 安裝及基本使用的教程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Spring中循環(huán)依賴的解決方法詳析

    Spring中循環(huán)依賴的解決方法詳析

    這篇文章主要給大家介紹了關于Spring中循環(huán)依賴的解決方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用spring具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • idea運行main方法或Test避免編譯整個應用的實現(xiàn)方法

    idea運行main方法或Test避免編譯整個應用的實現(xiàn)方法

    這篇文章主要介紹了idea運行main方法或Test避免編譯整個應用的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • spring boot密碼加密配置與實例詳解

    spring boot密碼加密配置與實例詳解

    BCrypt是一種專為密碼哈希設計的算法,它被廣泛認為是安全的選擇之一,這篇文章主要介紹了spring boot密碼加密配置與實例詳解,需要的朋友可以參考下
    2024-12-12
  • Java?在?Array?和?Set?之間進行轉換的示例

    Java?在?Array?和?Set?之間進行轉換的示例

    這篇文章主要介紹了Java如何在Array和Set之間進行轉換,在本文章中,我們對如何在?Java?中對Array和Set進行轉換進行一些說明和示例,需要的朋友可以參考下
    2023-05-05
  • SpringMVC響應視圖和結果視圖詳解

    SpringMVC響應視圖和結果視圖詳解

    這篇文章主要介紹了SpringMVC響應視圖和結果視圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

美姑县| 峨眉山市| 全州县| 电白县| 云霄县| 余江县| 定南县| 通化县| 陇西县| 正宁县| 双峰县| 日土县| 澄城县| 杭锦后旗| 邢台县| 家居| 区。| 宁阳县| 朔州市| 务川| 花垣县| 彩票| 天台县| 建水县| 青川县| 佛教| 海城市| 靖安县| 惠东县| 白银市| 渑池县| 揭西县| 尼勒克县| 宽城| 郧西县| 内乡县| 青阳县| 宣恩县| 横峰县| 浦东新区| 岢岚县|