002-从零搭建微服务-认证中心(二)

news2024/11/25 19:40:59

写在最前

如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

源码地址:https://gitee.com/csps/mingyue

文档地址:https://gitee.com/csps/mingyue/wikis

创建新项目 MingYue

Idea 创建 maven 项目这儿就不多赘述了,相信各位大佬都是信手拈来~

MingYue 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>

    <groupId>com.csp.mingyue</groupId>
    <artifactId>mingyue</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <name>MingYue</name>
    <description>MingYue 微服务系统</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>

    <!-- 以下依赖 全局所有的模块都会引入  -->
    <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>
        <!--测试依赖-->
        <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>

创建子项目 MingYue-Auth

Idea mingyue 右击 -> New -> Module

image-20230526103113168

核心依赖

<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 权限认证, 在线文档: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相关请求
	@RequestMapping("/oauth2/*")
	public Object request() {
		System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
		return SaOAuth2Handle.serverRequest();
	}

	// Sa-OAuth2 定制化配置
	@Autowired
	public void setSaOAuth2Config(SaOAuth2Config cfg) {
		cfg.
			// 未登录的视图
			setNotLoginView(()->{
				return new ModelAndView("login.html");
			}).
			// 登录处理函数
			setDoLoginHandle((name, pwd) -> {
				if("sa".equals(name) && "123456".equals(pwd)) {
					StpUtil.login(10001);
					return SaResult.ok();
				}
				return SaResult.error("账号名或密码错误");
			}).
			// 授权确认视图
			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());
	}


	// ---------- 开放相关资源接口: Client端根据 Access-Token ,置换相关资源 ------------

	// 获取Userinfo信息:昵称、头像、性别等等
	@RequestMapping("/oauth2/userinfo")
	public SaResult userinfo() {
		// 获取 Access-Token 对应的账号id
		String accessToken = SaHolder.getRequest().getParamNotNull("access_token");
		Object loginId = SaOAuth2Util.getLoginIdByAccessToken(accessToken);
		System.out.println("-------- 此Access-Token对应的账号id: " + loginId);

		// 校验 Access-Token 是否具有权限: userinfo
		SaOAuth2Util.checkScope(accessToken, "userinfo");

		// 模拟账号信息 (真实环境需要查询数据库获取信息)
		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", "山东省 青岛市 城阳区");
		return SaResult.data(map);
	}

}

SaOAuth2TemplateImpl

/**
 * Sa-Token OAuth2.0 整合实现
 * @author kong
 */
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {

	// 根据 id 获取 Client 信息
	@Override
	public SaClientModel getClientModel(String clientId) {
		// 此为模拟数据,真实环境需要从数据库查询
		if("1001".equals(clientId)) {
			return new SaClientModel()
					.setClientId("1001")
					.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
					.setAllowUrl("*")
					.setContractScope("userinfo")
					.setIsAutoMode(true);
		}
		return null;
	}

	// 根据ClientId 和 LoginId 获取openid
	@Override
	public String getOpenid(String clientId, Object loginId) {
		// 此为模拟数据,真实环境需要从数据库查询
		return "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__";
	}
}

添加 templates

  • confirm.html
  • login.html

创建启动类启动项目

@SpringBootApplication
public class MingYueAuthApplication {

	public static void main(String[] args) {
		SpringApplication.run(MingYueAuthApplication.class, args);
		System.out.println("\nSa-Token-OAuth  Server端启动成功: http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo");
	}

}

启动项目,访问打印地址:

Sa-Token-OAuth Server端启动成功: http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo

API 列表

共四种模式,分别是授权码(Authorization Code)、隐藏式(Implicit)、密码式(Password)、凭证式(Client Credentials),本文介绍了两种常用的:授权码(Authorization Code)、密码式(Password)

1. 授权码(Authorization Code)

http://localhost:9000/oauth2/authorize
?response_type=code
&client_id=1001
&redirect_uri=https://sa-token.cc&scope=userinfo

参数详解:

参数是否必填说明
response_type返回类型,这里请填写:code
client_id应用id
redirect_uri用户确认授权后,重定向的url地址
scope具体请求的权限,多个用逗号隔开
state随机值,此参数会在重定向时追加到url末尾,不填不追加

1.1 获取授权码

Code授权码具有以下特点:

  1. 每次授权产生的 Code 码都不一样
  2. Code码用完即废,不能二次使用
  3. 一个Code的有效期默认为五分钟,超时自动作废
  4. 每次授权产生新 Code 码,会导致旧 Code 码立即作废,即使旧 Code 码尚未使用

http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo

打开地址,登录并同意授权

image-20230525195925531

地址栏拿到 code https://sa-token.cc/?code=ct0RB10UkGSwXINdBkGRGVKBvoKjIi6jzeYi3NFrCwoXzDr36Ljgm1ZBplYx

1.2 根据授权码获取 Access-Token

浏览器直接访问:

http://localhost:9000/oauth2/token
    ?grant_type=authorization_code
    &client_id=1001
    &client_secret=aaaa-bbbb-cccc-dddd-eeee
    &code=ktN6FvIfB7pKqp7Thvkm32EfUhbveoybwOtmvqCCbuLdxevmyr9FW09Kd6qL
参数是否必填说明
grant_type授权类型,这里请填写:authorization_code
client_id应用id
client_secret应用秘钥
code步骤1.1中获取到的授权码

打印如下:

{
    "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 端构建表单,让用户输入 Server 端的账号和密码,然后在 Client 端访问接口

http://localhost:9000/oauth2/token
    ?grant_type=password
    &client_id=1001
    &client_secret=aaaa-bbbb-cccc-dddd-eeee
    &username=sa
    &password=123456
参数是否必填说明
grant_type返回类型,这里请填写:password
client_id应用id
client_secret应用秘钥
username用户的Server端账号
password用户的Server端密码
scope具体请求的权限,多个用逗号隔开

浏览器直接访问,打印如下:

{
    "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__"
    }
}

至此,一个基于 OAuth2 的认证中心 Demo 就完成啦,接下来我们先优化一下代码结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/621757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法与数据结构】59、LeetCode螺旋矩阵2

文章目录 题目一、方向向量法完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 题目 一、方向向量法 思路分析&#xff1a;螺旋矩阵在旋转过程中&#xff0c;我们选择的区间是左闭右开区间[ , ]&#xff0c;例如方向为从左往右…

【玩转Linux操作】Ubuntu创建桌面快捷方式

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题&#x1f970; 目录 &#x1f34e;进入applications文件夹 &#x1f34e;选择需要添加到…

chatgpt赋能python:Python开发平台软件的重要性

Python开发平台软件的重要性 随着科技的不断进步和软件开发的发展&#xff0c;Python语言逐渐成为最受欢迎和广泛使用的编程语言之一。作为一门高级编程语言&#xff0c;Python具有简单易懂的语法和强大的功能&#xff0c;能够帮助开发者快速构建复杂的应用程序和网站。Python…

初学者应该怎么学git-下

初学者应该怎么学git-下 Git 文件管理 文件四种状态 ● 版本控制就是对文件的版本控制&#xff0c;在Git 管理中&#xff0c;文件被统一管理&#xff0c;有四个状态 Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git 库, 不参与版本控制. 通过git add 状态变为Stage…

高性能网络应用框架

技术主题 Netty从本质上讲是一个高性能网络应用框架&#xff0c;之所以说是高性能&#xff0c;依赖于Netty的线程模型。 一网络编程性能的瓶颈 BIO 模型里&#xff0c; read() 操作和 write() 操作都会阻塞当前线程的&#xff0c;如果客户端已经和服务端建立了一个连接&…

【基于IMX6ULL驱动开发学习】01.安装交叉编译环境【附下载地址】

第一步&#xff08;下载工具链&#xff09;&#xff1a; 从官网上下载交叉编译工具链 https://snapshots.linaro.org/gnu-toolchain/ 按照以下步骤选择 可以选择最新的&#xff08;我也忘记我用的哪个版本了&#xff0c;都可以用问题不大&#xff09; 第二步&#xff08;…

chatgpt赋能python:Python库函数:提高开发效率的利器

Python库函数&#xff1a;提高开发效率的利器 Python作为一门高级编程语言&#xff0c;被广泛应用于 Web开发、科学计算、机器学习、数据分析等领域。它的可读性强、语法简单、库函数丰富是其广受欢迎的原因之一。本文将带您了解Python库函数的优势并介绍几个常用的库函数。 …

大型语言模(LLM) 之 提示词工程(三)

今天我学习了DeepLearning.AI的 Prompt Engineering 的在线课程&#xff0c;我想和大家一起分享一下该门课程的一些主要内容。以下是我写的关于该课程的前两篇博客&#xff1a; 大型语言模(LLM)之提示词工程(一) 大型语言模(LLM)之提示词工程(二) 今天我们来学习第三部分内容…

【express模块】课程笔记

目标&#xff1a; express.static()快速托管静态资源express路由精简项目结构常见express中间件使用express创建API接口在express中启用cors跨域资源共享 目录 一. 初识Express 1.1 Express简介 1. 什么是express 2. 进一步理解Express 3. Express能做什么 1.2 Express…

聊聊那些奇葩的代码规范 —— 滥用 lombok

因为有些要求感觉实是太过奇葩&#xff0c;收集下来娱乐下大家。 代码规范要求 在所有无参数构造函数&#xff0c;全参数构造函数&#xff0c;Getter 和 Setter 方法必须要使用 Lombok。 所有的 Builder 方法也必须要用 Lombok。 简单来说是就是 Lombok 没有提供的才可以使用…

《统计学习方法》——逻辑斯谛回归与最大熵模型(上)

引言 逻辑斯谛回归(logistic regression)是统计学习中的经典分类方法。最大熵是概率模型学习的一个准则&#xff0c;将其推广到分类问题得到最大熵模型(maximum entropy model)。 由于后面最优化方法中用到了最优化理论中的一些知识&#xff0c;建议先阅读最优化简介。 逻辑…

chatgpt赋能python:Python开发环境的安装方法

Python开发环境的安装方法 Python已经成为了当今最流行的编程语言之一&#xff0c;它易于学习和使用&#xff0c;而且庞大的社区提供了大量的资源和库。那么&#xff0c;如果你是一位Python初学者或新手&#xff0c;本篇文章将为您介绍如何安装Python开发环境。 Python环境的…

技巧:win10的另一种美化字体的方式,使用noMeiryoUI

目录 1. 前提2. 字体选择3. 查看已经安装的字体并查看效果4. 安装软件修改系统字体5. 修改浏览器字体 1. 前提 21年的时候写了一篇文章&#xff0c;《Windows10下美化字体&#xff0c;达到类似mac的效果》&#xff0c;当时还很迷恋macType这个软件的使用&#xff0c;觉得好牛逼…

DAY11——栈与队列part2

双端队列Deque——Double ended Queue 插入和删除为O(1), 查询为O(n) 使用Deque - 廖雪峰的官方网站 (liaoxuefeng.com) Priority Queue 优先级队列 插入操作 O(1) 取出元素O(logN)——按照元素的优先级取出 底层数据结构为heap&#xff0c;bst... 题目一 最近相关性——使…

《Reinforcement Learning: An Introduction》第3章笔记

Chapter 3 Finite Markov Decision 本章正式介绍有限马尔科夫决策过程(finite Markov decision processes, finite MDP)&#xff0c; 它包括第二章介绍的评估性反馈和关联(associative)—在不同情景下选择不同的状态。 MDP是序贯决策问题的经典形式化表达&#xff0c;它的动作…

【玩转Linux操作】硬链接和软连接

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题&#x1f970; 欢迎大家访问“在下小吉.”&#xff08;偷偷告诉你这个是我的大号哦&#…

创客匠人5月活动总结

为了帮助老师做好知识变现、拓客增长&#xff0c;让好老师走进千万家&#xff0c;让知识创造价值&#xff0c;五月&#xff0c;创客匠人组织了一系列线上线下干货满满的赋能活动&#xff01; 一、老蒋商业变现营线上 5月10日-5月14日&#xff0c;在线上举办了首期【老蒋商业变现…

C++作业day1

思维导图 有以下定义&#xff0c;说明哪些量可以改变哪些不可以改变&#xff1f; const char *p; p指向的指向不能修改 const (char *) p; char *const p; p不能改 const char* const p; 都不能修改 …

Python对接亚马逊电商平台SP-API的一些概念理解准备

❝ 除了第三方服务商&#xff0c;其实亚马逊卖家本身也可以通过和SP-API的对接&#xff0c;利用程序来自动化亚马逊店铺销售运营管理中很多环节的工作&#xff0c;简单的应用比如可以利用SP-API的对接&#xff0c;实现亚马逊卖家后台各类报表的定期自动下载以及数据分析整理工…

分享两个小众的办公软件

01 Apache OpenOffice是一款开源办公套件软件&#xff0c;主要用于文档处理、电子表格、演示文稿和数据库管理等方面。它包括Writer、Calc、Impress、Draw和Base五个组件。 Writer是Apache OpenOffice的文本编辑器&#xff0c;可用于创建各种类型的文档&#xff0c;如信函、报…