寫在最前
如果這個(gè)項(xiàng)目讓你有所收獲,記得 Star 關(guān)注哦,這對(duì)我是非常不錯(cuò)的鼓勵(lì)與支持。
源碼地址(后端):https://gitee.com/csps/mingyue-springcloud-learning
源碼地址(前端):https://gitee.com/csps/mingyue-springcloud-ui
文檔地址:https://gitee.com/csps/mingyue-springcloud-learning/wikis
創(chuàng)建新項(xiàng)目 MingYue
Idea 創(chuàng)建 maven 項(xiàng)目這兒就不多贅述了,相信各位大佬都是信手拈來~
MingYue Pom
父項(xiàng)目的依賴都放在這兒了,后續(xù)用到什么再增加什么
<?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>
<groupId>com.csp.mingyue</groupId>
<artifactId>mingyue</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>MingYue</name>
<description>MingYue 微服務(wù)系統(tǒng)</description>
<properties>
<mingyue.version>1.0.0</mingyue.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<!-- Spring 版本 -->
<spring-boot.version>2.7.11</spring-boot.version>
<spring-cloud.version>2021.0.6</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
<!-- 工具版本 -->
<jasypt.version>3.0.5</jasypt.version>
<hutool.version>5.8.18</hutool.version>
<lombok.version>1.18.26</lombok.version>
<spring.checkstyle.plugin>0.0.38</spring.checkstyle.plugin>
</properties>
<!-- 以下依賴 全局所有的模塊都會(huì)引入 -->
<dependencies>
<!--配置文件處理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--配置文件加解密-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.version}</version>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--測(cè)試依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 依賴聲明 -->
<dependencyManagement>
<dependencies>
<!-- spring boot 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 依賴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- hutool 的依賴配置-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
創(chuàng)建子項(xiàng)目 MingYue-Auth
Idea
mingyue
右擊 ->New
->Module
核心依賴
<properties>
<sa-token.version>1.34.0</sa-token.version>
</properties>
<dependencies>
<!-- SpringBoot依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Sa-Token 權(quán)限認(rèn)證, 在線文檔:https://sa-token.cc/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token-OAuth2.0 模塊 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- 提供Redis連接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 視圖引擎(在前后端不分離模式下提供視圖支持) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
SaOAuth2ServerController
/**
* Sa-OAuth2 Server端 控制器
* @author kong
*
*/
@RestController
public class SaOAuth2ServerController {
// 處理所有OAuth相關(guān)請(qǐng)求
@RequestMapping("/oauth2/*")
public Object request() {
System.out.println("------- 進(jìn)入請(qǐng)求: " + SaHolder.getRequest().getUrl());
return SaOAuth2Handle.serverRequest();
}
// Sa-OAuth2 定制化配置
@Autowired
public void setSaOAuth2Config(SaOAuth2Config cfg) {
cfg.
// 未登錄的視圖
setNotLoginView(()->{
return new ModelAndView("login.html");
}).
// 登錄處理函數(shù)
setDoLoginHandle((name, pwd) -> {
if("sa".equals(name) && "123456".equals(pwd)) {
StpUtil.login(10001);
return SaResult.ok();
}
return SaResult.error("賬號(hào)名或密碼錯(cuò)誤");
}).
// 授權(quán)確認(rèn)視圖
setConfirmView((clientId, scope)->{
Map<String, Object> map = new HashMap<>();
map.put("clientId", clientId);
map.put("scope", scope);
return new ModelAndView("confirm.html", map);
})
;
}
// 全局異常攔截
@ExceptionHandler
public SaResult handlerException(Exception e) {
e.printStackTrace();
return SaResult.error(e.getMessage());
}
// ---------- 開放相關(guān)資源接口: Client端根據(jù) Access-Token ,置換相關(guān)資源 ------------
// 獲取Userinfo信息:昵稱、頭像、性別等等
@RequestMapping("/oauth2/userinfo")
public SaResult userinfo() {
// 獲取 Access-Token 對(duì)應(yīng)的賬號(hào)id
String accessToken = SaHolder.getRequest().getParamNotNull("access_token");
Object loginId = SaOAuth2Util.getLoginIdByAccessToken(accessToken);
System.out.println("-------- 此Access-Token對(duì)應(yīng)的賬號(hào)id: " + loginId);
// 校驗(yàn) Access-Token 是否具有權(quán)限: userinfo
SaOAuth2Util.checkScope(accessToken, "userinfo");
// 模擬賬號(hào)信息 (真實(shí)環(huán)境需要查詢數(shù)據(jù)庫(kù)獲取信息)
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("nickname", "shengzhang_");
map.put("avatar", "http://xxx.com/1.jpg");
map.put("age", "18");
map.put("sex", "男");
map.put("address", "山東省 青島市 城陽(yáng)區(qū)");
return SaResult.data(map);
}
}
SaOAuth2TemplateImpl
/**
* Sa-Token OAuth2.0 整合實(shí)現(xiàn)
* @author kong
*/
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
// 根據(jù) id 獲取 Client 信息
@Override
public SaClientModel getClientModel(String clientId) {
// 此為模擬數(shù)據(jù),真實(shí)環(huán)境需要從數(shù)據(jù)庫(kù)查詢
if("1001".equals(clientId)) {
return new SaClientModel()
.setClientId("1001")
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
.setAllowUrl("*")
.setContractScope("userinfo")
.setIsAutoMode(true);
}
return null;
}
// 根據(jù)ClientId 和 LoginId 獲取openid
@Override
public String getOpenid(String clientId, Object loginId) {
// 此為模擬數(shù)據(jù),真實(shí)環(huán)境需要從數(shù)據(jù)庫(kù)查詢
return "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__";
}
}
添加 templates
- confirm.html
- login.html
創(chuàng)建啟動(dòng)類啟動(dòng)項(xiàng)目
@SpringBootApplication
public class MingYueAuthApplication {
public static void main(String[] args) {
SpringApplication.run(MingYueAuthApplication.class, args);
System.out.println("\nSa-Token-OAuth Server端啟動(dòng)成功: http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo");
}
}
啟動(dòng)項(xiàng)目,訪問打印地址:
Sa-Token-OAuth Server端啟動(dòng)成功: http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo
API 列表
共四種模式,分別是授權(quán)碼(Authorization Code)、隱藏式(Implicit)、密碼式(Password)、憑證式(Client Credentials),本文介紹了兩種常用的:授權(quán)碼(Authorization Code)、密碼式(Password)
1. 授權(quán)碼(Authorization Code)
http://localhost:9000/oauth2/authorize
?response_type=code
&client_id=1001
&redirect_uri=https://sa-token.cc&scope=userinfo
參數(shù)詳解:
參數(shù) | 是否必填 | 說明 |
---|---|---|
response_type | 是 | 返回類型,這里請(qǐng)?zhí)顚懀篶ode |
client_id | 是 | 應(yīng)用id |
redirect_uri | 是 | 用戶確認(rèn)授權(quán)后,重定向的url地址 |
scope | 否 | 具體請(qǐng)求的權(quán)限,多個(gè)用逗號(hào)隔開 |
state | 否 | 隨機(jī)值,此參數(shù)會(huì)在重定向時(shí)追加到url末尾,不填不追加 |
1.1 獲取授權(quán)碼
Code授權(quán)碼具有以下特點(diǎn):
- 每次授權(quán)產(chǎn)生的 Code 碼都不一樣
- Code碼用完即廢,不能二次使用
- 一個(gè)Code的有效期默認(rèn)為五分鐘,超時(shí)自動(dòng)作廢
- 每次授權(quán)產(chǎn)生新 Code 碼,會(huì)導(dǎo)致舊 Code 碼立即作廢,即使舊 Code 碼尚未使用
http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo
打開地址,登錄并同意授權(quán)
地址欄拿到
code
https://sa-token.cc/?code=ct0RB10UkGSwXINdBkGRGVKBvoKjIi6jzeYi3NFrCwoXzDr36Ljgm1ZBplYx
1.2 根據(jù)授權(quán)碼獲取 Access-Token
瀏覽器直接訪問:
http://localhost:9000/oauth2/token
?grant_type=authorization_code
&client_id=1001
&client_secret=aaaa-bbbb-cccc-dddd-eeee
&code=ktN6FvIfB7pKqp7Thvkm32EfUhbveoybwOtmvqCCbuLdxevmyr9FW09Kd6qL
參數(shù) | 是否必填 | 說明 |
---|---|---|
grant_type | 是 | 授權(quán)類型,這里請(qǐng)?zhí)顚懀篴uthorization_code |
client_id | 是 | 應(yīng)用id |
client_secret | 是 | 應(yīng)用秘鑰 |
code | 是 | 步驟1.1中獲取到的授權(quán)碼 |
打印如下:
{
"code": 200,
"msg": "ok",
"data": {
"access_token": "E1ZLgNXLiUIz8DmAxmgPeegMPsUCEJJLjUV9uwDQWCu4f6Tgg8U5JqKSrqSx",
"refresh_token": "0IAWolcbMvoIpF8F1JcEuytfcoTe8nNVwsEdUHOy7rBX0V99vhPBvtFGfh62",
"expires_in": 7199,
"refresh_expires_in": 2591999,
"client_id": "1001",
"scope": "userinfo",
"openid": "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__"
}
}
2. 密碼式(Password)
首先在 Client 端構(gòu)建表單,讓用戶輸入 Server 端的賬號(hào)和密碼,然后在 Client 端訪問接口
http://localhost:9000/oauth2/token
?grant_type=password
&client_id=1001
&client_secret=aaaa-bbbb-cccc-dddd-eeee
&username=sa
&password=123456
參數(shù) | 是否必填 | 說明 |
---|---|---|
grant_type | 是 | 返回類型,這里請(qǐng)?zhí)顚懀簆assword |
client_id | 是 | 應(yīng)用id |
client_secret | 是 | 應(yīng)用秘鑰 |
username | 是 | 用戶的Server端賬號(hào) |
password | 是 | 用戶的Server端密碼 |
scope | 否 | 具體請(qǐng)求的權(quán)限,多個(gè)用逗號(hào)隔開 |
瀏覽器直接訪問,打印如下:文章來源:http://www.zghlxwxcb.cn/news/detail-487525.html
{
"code": 200,
"msg": "ok",
"data": {
"access_token": "BvU1yja6sy4WT3orCvIiYExIOhGMBwVps38ZywZWGaeYaM6nJbPkJRbHpmSC",
"refresh_token": "TzSGmGhtPuAZUZ5ndfVETdmmpGr3ZwAH5N5kbrEYeeR2LKbLBXEysqsLxuV6",
"expires_in": 7199,
"refresh_expires_in": 2591999,
"client_id": "1001",
"scope": "",
"openid": "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__"
}
}
至此,一個(gè)基于 OAuth2 的認(rèn)證中心 Demo 就完成啦,接下來我們先優(yōu)化一下代碼結(jié)構(gòu)。文章來源地址http://www.zghlxwxcb.cn/news/detail-487525.html
到了這里,關(guān)于002-從零搭建微服務(wù)-認(rèn)證中心(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!