Spring Boot項目中集成sa-token實現認證授權和OAuth 2.0第三方登錄

OAuth 2.0第三方登錄

OAuth 2.0 是一種授權協議,允許第三方應用在不暴露用戶密碼的情況下訪問用戶的資源。它通常用于第三方登錄場景,例如使用GitHub、Google等社交平臺進行登錄。

sa-token框架中,OAuth 2.0第三方登錄可以通過集成sa-token-oauth2模塊來實現,并且可以結合sa-token的安全特性來增強安全性。

導入依賴

首先,在你的pom.xml文件中添加必要的依賴,包括sa-token核心模塊、MyBatis、數據庫驅動等,特別是要導入sa-token-oauth2模塊。

<dependencies><!-- sa-token 核心模塊 -->//如果你使用的是 SpringBoot 3.x,只需要將 sa-token-spring-boot-starter 修改為 sa-token-spring-boot3-starter 即可。<dependency><groupId>cn.dev33</groupId><artifactId>sa-token-spring-boot-starter</artifactId><version>1.40.0</version></dependency><!-- Sa-Token OAuth2.0 模塊 --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-oauth2</artifactId><version>1.40.0</version></dependency><!-- MyBatis Spring Boot Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><!-- MySQL Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- Lombok  --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- JSON  --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- Sa-Token SSO  --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-sso-spring-boot-starter</artifactId><version>1.40.0</version></dependency>
</dependencies>

配置?application.yml

application.yml中配置sate-token、數據庫連接信息以及OAuth 2.0提供商的信息。

server:port: 8080 # 應用端口sa-token:token-name: satoken  # 指定token的名稱,默認是satokentimeout: 7200        # 超時時間 (單位秒),這里是2小時is-read-body: true   # 是否讀取請求體,默認是trueis-concurrent: false # 是否允許多端登錄,默認是falseis-share: true       # 是否共享Session信息,默認是truetoken-style: uuid    # Token生成風格,默認是uuidsso:login-url: /sso/login # 單點登錄入口地址logout-url: /sso/logout # 單點注銷入口地址callback-url: /sso/callback # 單點登錄回調地址oauth2:client:github:client-id: your-client-id # 替換為你的GitHub Client IDclient-secret: your-client-secret # 替換為你的GitHub Client Secretredirect-uri: "{baseUrl}/oauth2/code/github" # 回調地址模板scope: read:user,user:email # 請求的范圍user-info-uri: https://api.github.com/user # 用戶信息獲取URLauthorization-uri: https://github.com/login/oauth/authorize # 授權URLtoken-uri: https://github.com/login/oauth/access_token # Token獲取URLspring:datasource:url: jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTCusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xml # MyBatis Mapper XML 文件位置type-aliases-package: com.example.demo.entity # 實體類包路徑

?初始化數據

你可以使用以下SQL語句初始化一些測試數據:

CREATE TABLE users (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255) NOT NULL UNIQUE,password VARCHAR(255) NOT NULL
);CREATE TABLE permissions (id BIGINT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL
);CREATE TABLE user_permissions (user_id BIGINT NOT NULL,permission_id BIGINT NOT NULL,FOREIGN KEY (user_id) REFERENCES users(id),FOREIGN KEY (permission_id) REFERENCES permissions(id)
);INSERT INTO users (username, password) VALUES ('admin', 'password');
INSERT INTO permissions (name) VALUES ('admin:manage'), ('user:view');INSERT INTO user_permissions (user_id, permission_id) 
SELECT u.id, p.id FROM users u, permissions p WHERE u.username = 'admin' AND p.name IN ('admin:manage', 'user:view');

DTO類

創建一個簡單的DTO類用于接收登錄請求的數據。

UserLoginDTO.java
package com.example.demo.dto;public class UserLoginDTO {private String username;private String password;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;}
}

創建實體類

創建UserPermission實體類,并映射到數據庫表。

User.java
package com.example.demo.entity;import lombok.Data;
import java.util.Set;@Data
public class User {private Long id; // 用戶IDprivate String username; // 用戶名private String password; // 密碼private Set<String> permissions; // 權限集合(簡化版,直接存儲權限字符串)
}
Permission.java
package com.example.demo.entity;import lombok.Data;@Data
public class Permission {private Long id;private String name; // 權限名稱
}

創建Mapper接口

創建UserMapper接口來訪問數據庫。

UserMapper.java
package com.example.demo.mapper;import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserMapper {/*** 根據用戶名查找用戶及其權限* @param username 用戶名* @return 用戶對象*/@Select("SELECT u.id, u.username, u.password FROM users u WHERE u.username = #{username}")User findByUsername(@Param("username") String username);/*** 查找用戶的權限列表* @param userId 用戶ID* @return 權限集合*/@Select("SELECT p.name FROM user_permissions up JOIN permissions p ON up.permission_id = p.id WHERE up.user_id = #{userId}")List<String> findPermissionsByUserId(@Param("userId") Long userId);
}

創建Service層

創建UserService接口及其實現類。

UserService.java
package com.example.demo.service;import com.example.demo.entity.User;public interface UserService {User findByUsername(String username); // 根據用戶名查找用戶
}
UserServiceImpl.java
package com.example.demo.service.impl;import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.HashSet;
import java.util.List;
import java.util.Set;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic User findByUsername(String username) {// 查找用戶基本信息User user = userMapper.findByUsername(username);if (user != null) {// 查找用戶的權限列表List<String> permissionNames = userMapper.findPermissionsByUserId(user.getId());Set<String> permissions = new HashSet<>(permissionNames);user.setPermissions(permissions);}return user;}
}

創建Controller層

創建LoginController類來處理用戶的登錄請求。

LoginController.java
package com.example.demo.controller;import com.example.demo.dto.UserLoginDTO;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.info.SaTokenInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;@RestController
public class LoginController {@Autowiredprivate UserService userService; // 自動注入UserService/*** 處理用戶登錄請求* @param loginDTO 登錄信息* @return 登錄結果*/@PostMapping("/login") // 映射HTTP POST請求到/login路徑public ResponseEntity<String> login(@RequestBody UserLoginDTO loginDTO) { // 接收JSON格式的登錄信息String username = loginDTO.getUsername(); // 獲取用戶名String password = loginDTO.getPassword(); // 獲取密碼// 查找用戶User user = userService.findByUsername(username); // 從數據庫查找用戶if (user != null && password.equals(user.getPassword())) { // 驗證密碼StpUtil.login(user.getId()); // 登錄用戶,參數為用戶IDfor (String permission : user.getPermissions()) {StpUtil.setPermission(permission); // 設置用戶權限}SaTokenInfo tokenInfo = StpUtil.getTokenInfo(); // 獲取token信息return ResponseEntity.ok("登錄成功, Token: " + tokenInfo.getTokenValue()); // 返回登錄成功消息}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用戶名或密碼錯誤"); // 返回錯誤消息}
}

權限校驗

使用注解@SaCheckPermission對需要權限控制的方法進行保護。

AdminController.java
package com.example.demo.controller;import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/admin")
public class AdminController {/*** 管理后臺接口* @return 管理后臺頁面內容*/@SaCheckPermission(value = "admin:manage") // 檢查當前用戶是否有"admin:manage"權限@GetMapping("/manage") // 映射GET請求到/admin/manage路徑public String manage() {return "管理后臺"; // 如果權限檢查通過,則返回管理后臺頁面內容}
}

OAuth 2.0集成

對于OAuth 2.0第三方登錄,我們可以使用sa-token-oauth2模塊提供的功能來實現。

OAuth2Controller.java
package com.example.demo.controller;import cn.dev33.satoken.oauth2.logic.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.AuthTokenModel;
import cn.dev33.satoken.oauth2.model.UserInfoModel;
import cn.dev33.satoken.oauth2.model.CodeModel;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@RestController
@RequestMapping("/oauth2")
public class OAuth2Controller {@GetMapping("/login/github")public void loginGithub(HttpServletResponse response) throws IOException {// GitHub登錄SaOAuth2Config config = SaOAuth2Manager.getConfig(SaOAuth2Consts.GITHUB);SaOAuth2Handle.redirectTo(config);}@GetMapping("/code/github")public String callbackGithub(@RequestParam String code, @RequestParam String state) {// GitHub回調處理SaOAuth2Config config = SaOAuth2Manager.getConfig(SaOAuth2Consts.GITHUB);CodeModel codeModel = new CodeModel(code, state);AccessTokenModel accessTokenModel = SaOAuth2Handle.getAccessToken(config, codeModel);UserInfoModel userInfoModel = SaOAuth2Handle.getUserInfo(config, accessTokenModel);// 這里可以添加將用戶信息保存到數據庫的邏輯return "登錄成功,歡迎:" + userInfoModel.getUsername();}
}

總結

以上步驟詳細描述了如何在Spring Boot項目中集成sa-token實現認證授權和OAuth 2.0第三方登錄。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73288.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73288.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73288.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字化新零售與 AI 大模型,如何重塑大健康賽道??

在數字化浪潮中&#xff0c;大健康賽道正經歷深刻變革。數字化新零售營銷模式的興起&#xff0c;與 AI 大模型的強大能力相結合&#xff0c;為大健康領域帶來了全新的發展機遇。 數字化新零售營銷模式融合線上線下&#xff0c;運用大數據、云計算分析消費者行為&#xff0c;實…

高速PCB設計(布線設計)

以下是針對高速PCB布線設計的綜合筆記&#xff0c;結合用戶提供的設計規范及行業通用原則整理而成&#xff1a; 一、關鍵信號布線原則 布線優先級 順序&#xff1a;射頻信號&#xff1e;中/低頻信號&#xff1e;時鐘信號&#xff1e;高速信號射頻信號需包地處理&#xff0c;線…

宇樹ROS1開源模型在ROS2中Gazebo中仿真

以GO1為例 1. CMakelists.txt更新語法 cmake_minimum_required(VERSION 3.8) project(go1_description) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find…

嵌入式學習第二十四天--網絡 服務器

服務器模型 tcp服務器: socket bind listen accept recv/send close 1.支持多客戶端訪問 //單循環服務器 socket bind listen while(1) { accept while(1) { recv/send } } close 2.支持多客戶端同時訪問 (并發能力) 并發服務器 socket bind …

使用GPTQ量化Llama-3-8B大模型

使用GPTQ量化8B生成式語言模型 服務器配置&#xff1a;4*3090 描述&#xff1a;使用四張3090&#xff0c;分別進行單卡量化&#xff0c;多卡量化。并使用SGLang部署量化后的模型&#xff0c;使用GPTQ量化 原來的模型精度為FP16&#xff0c;量化為4bit 首先下載gptqmodel量化…

防汛應急包,快速響應,守護安全

根據中國水利部統計&#xff0c;自1949年以來&#xff0c;我國幾乎每年都面臨洪水威脅&#xff0c;其中20世紀90年代后洪澇災害頻率顯著增加&#xff0c;僅1990-2009年間就發生超4000起較大災害&#xff0c;直接經濟損失近3萬億元&#xff0c;受災人口達20億人次。在2020年長江…

從 Vue 到 React:理解作用與副作用

作用 VS 副作用 響應式作用&#xff1a; 響應式作用是 Vue 響應式系統的一部分&#xff0c;它指的是跟蹤函數的依賴關系&#xff0c;并在它們的值發生變化時重新運行該函數的過程。watchEffect 是最直接的創建作用的方式&#xff08;如 watch 和 computed&#xff09;。 副作…

a = b c 的含義

簡單一句話&#xff1a; result condition && value; condition 為真取 value的值&#xff0c;condition為假就取condition的值&#xff0c;真取后假取前 // 示例 1: b 為真值 let b 1; let c 2; let a b && c; console.log(a); // 輸出: 2// 示例 2: b 為…

【大模型系列】llama.cpp本地運行大模型

上一篇鏈接: 【大模型系列】使用ollama本地運行千問2.5模型 我們講了ollama本地運行大模型&#xff0c;這里我們介紹另一種本地運行大模型的方法&#xff1a;llamacpp 軟件下載 下載地址&#xff1a;https://github.com/ggml-org/llama.cpp/releases 下載cpu版本的llamacpp&a…

PyQt基礎——簡單的圖形化界面(窗口)

一、代碼展示 import sysfrom PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QLineEdit, QPushButton from PyQt6 import uic from PyQt6.QtCore import Qt# 封裝一個我的窗口類 class MyWidget(QWidget):def __init__(self):supe…

泰山派開發之—Ubuntu24.04下Linux開發環境搭建

簡介 最近翻到了吃灰已久的泰山派&#xff0c;是剛出來的時候用優惠券買的&#xff0c;當時價格挺便宜的&#xff0c;最近給它翻出來了&#xff0c;打算試試做個項目。買的泰山派容量是2G16G&#xff0c;SOC芯片使用的是RK3566&#xff0c;搭載1TOP算力的NPU&#xff0c;并且具…

HTTP 協議中常見的錯誤狀態碼(詳細介紹)

以下是 HTTP 協議中常見的錯誤狀態碼及其原因的總結&#xff0c;按錯誤類型分類整理&#xff1a; 4xx 客戶端錯誤 400 Bad Request 原因&#xff1a;請求格式錯誤&#xff0c;服務器無法解析。常見場景&#xff1a; 請求頭或請求體語法錯誤&#xff08;如 JSON/XML 格式錯誤…

kkFileView文件預覽組件部署說明

kkFileView組件部署流程指南 在數字化辦公與文件管理場景中&#xff0c;在線文件預覽功能極為關鍵。kkFileView作為一款優秀的開源在線文件預覽組件&#xff0c;支持多種格式文件的預覽&#xff0c;為企業和開發者提供了便捷的解決方案。下面將詳細介紹其部署步驟。 一、前期準…

[React Native]Stack、Tab和Drawer導航器詳解

對于StackNavigator&#xff0c;網頁[1]提到它用于頁面間的層級跳轉&#xff0c;使用棧結構管理頁面。網頁[4]和[8]詳細說明了navigationOptions的配置&#xff0c;比如標題、頭部樣式等。網頁[3]展示了如何在Stack中嵌入Tab導航&#xff0c;這可以作為組合使用的例子。 TabNa…

激光雷達產業觀察--速騰聚創發展脈絡2025.3.14

一.發展歷程 1.1 企業創立 速騰聚創的創立可追溯至2014年8月28日&#xff0c;這家充滿活力的高科技企業誕生于中國深圳。公司創始人邱純鑫是一位富有遠見的企業家&#xff0c;他的創業之路充滿了創新精神和技術洞察力。 邱純鑫的創業靈感源于他在哈爾濱工業大學深圳校區的學…

Kubernetes 網絡方案全解析:Flannel、Calico 與 Cilium 對比與選擇

文章目錄 Kubernetes 網絡方案全解析&#xff1a;Flannel、Calico 與 Cilium 對比與選擇Flannel —— 輕量級基礎網絡簡介核心特性適用場景 Calico —— 高性能與安全兼備的成熟方案簡介核心特性適用場景 Cilium —— 基于 eBPF 的下一代網絡方案簡介核心特性適用場景 深入對比…

OpenCV實現圖像分割與無縫合并

一、圖像分割核心方法 1、閾值分割 #include <opencv2/opencv.hpp> using namespace cv; int main() {Mat img imread("input.jpg", IMREAD_GRAYSCALE);Mat binary;threshold(img, binary, 127, 255, THRESH_BINARY); // 固定閾值分割imwrite("binary.…

計算機視覺算法實戰——駕駛員分心檢測(主頁有源碼)

?個人主頁歡迎您的訪問 ?期待您的三連 ? ?個人主頁歡迎您的訪問 ?期待您的三連 ? ?個人主頁歡迎您的訪問 ?期待您的三連? ? ??? 1. 領域簡介&#xff1a;駕駛員分心檢測的意義與挑戰 駕駛員分心檢測是智能駕駛安全領域的重要研究方向。據統計&#xff0c;全球每…

scoop退回軟件版本的方法

title: scoop退回軟件版本的方法 date: 2025-3-11 23:53:00 tags: 其他 前言 在軟件更新后&#xff0c;如果出現了很影響使用體驗的問題&#xff0c;那么可以把軟件先退回以前的版本進行使用&#xff0c; 但是scoop本身并沒有提供直接讓軟件回退版本的功能&#xff0c;因此…

OpenRewrite配方之import語句的順序——org.openrewrite.java.OrderImports

org.openrewrite.java.OrderImports 是 OpenRewrite 工具庫中的一個重要規則(Recipe),專為 Java 項目設計,用于自動化調整 import 語句的順序,使其符合預定義的代碼規范。從而提高代碼的一致性和可讀性。 核心功能 排序規則: 靜態導入優先:默認將靜態導入(import stati…