从零搭建微服务-认证中心(二)
写在最前
如果这个项目让你有所收获,记得 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
核心依赖
<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 定制化配置@Autowiredpublic 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);});}// 全局异常拦截@ExceptionHandlerpublic SaResult handlerException(Exception e) {e.printStackTrace();return SaResult.error(e.getMessage());}// ---------- 开放相关资源接口: Client端根据 Access-Token ,置换相关资源 ------------// 获取Userinfo信息:昵称、头像、性别等等@RequestMapping("/oauth2/userinfo")public SaResult userinfo() {// 获取 Access-Token 对应的账号idString accessToken = SaHolder.getRequest().getParamNotNull("access_token");Object loginId = SaOAuth2Util.getLoginIdByAccessToken(accessToken);System.out.println("-------- 此Access-Token对应的账号id: " + loginId);// 校验 Access-Token 是否具有权限: userinfoSaOAuth2Util.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 信息@Overridepublic 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@Overridepublic 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授权码具有以下特点:
- 每次授权产生的 Code 码都不一样
- Code码用完即废,不能二次使用
- 一个Code的有效期默认为五分钟,超时自动作废
- 每次授权产生新 Code 码,会导致旧 Code 码立即作废,即使旧 Code 码尚未使用
http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=https://sa-token.cc&scope=userinfo
打开地址,登录并同意授权
地址栏拿到
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 就完成啦,接下来我们先优化一下代码结构。
相关文章:

从零搭建微服务-认证中心(二)
写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址:https://gitee.com/csps/mingyue 文档地址:https://gitee.com/csps/mingyue/wikis 创建新项目 MingYue Idea 创建 maven 项目这…...
python入门(11)面向对象 :模块与包
1. 模块 1.1 什么是模块 在 Python 中,模块是一个包含了函数、类和变量的文件。模块提供了一种组织代码的方式,使得代码更加可重用和可维护。你可以使用 Python 内置的模块,也可以创建自己的模块。 Python 模块的特点包括: 封装…...

《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记
写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理…...
【数据结构】第六周
目录 银行排队——队列 公共钥匙盒——队列 等值子串 KMP模式匹配 大整数相乘 最长公共子串 银行排队——队列 【问题描述】 我们大多都有在银行排队的经历,唉,那坑爹的排队啊!现在就让我们来算算我们这些客户平均需要等多久吧。 每天…...

6.4.6拓扑排序
用DAG(有向无环图)表示一个工程。顶点表示活动,有向边<Vi,Vj>表示活动Vi活动必须先与Vj活动进行。 所谓的拓扑排序:找到做事的先后顺序 以上根据拓扑排序的实现: 加入对有回路的图进行拓扑排序&#…...

Ae:常用内置抠像效果
Ae 中的抠像都是基于效果控件来实现的,最终生成动态遮罩来控制画面像素的透明度。 常用的内置抠像效果有:提取、线性颜色键、颜色差值键、内部/外部键等。 黑色或白色背景的抠像 对于白色或黑色背景的素材,可直接尝试图层混合模式。 或者&…...
[ 支付宝支付笔记]
目录 前言: 支付宝支付: 创建AlipayClient对象(注意,这里的appId、私钥、公钥等信息需要根据实际情况进行替换): 构造AlipayTradePagePayRequest对象,设置订单信息等参数: 调用AlipayClient对象的page…...

2023九坤投资暑期实习笔试复盘
5.22号笔试,5.24确认自己笔试挂。想想这也是自己第一次做量化私募基金的笔试,在此复盘一下。情况:北邮本硕。但开始准备暑期准备的比较晚,4月初才开始一边刷题一边投简历,所以手撕算法不太强,但运气和灵感好…...

深度学习的定义和未来发展趋势
深度学习的定义和未来发展趋势 什么是深度学习数学和编程的基础知识深度学习的应用领域深度学习的常见算法和模型训练深度学习模型深度学习的未来 🏘️🏘️个人简介:以山河作礼。 🎖️🎖️:Python领域新星创作者&#…...

如何更改 Linux 文件和目录权限?
在Linux系统中,文件和目录权限是安全性和访问控制的关键组成部分。正确设置文件和目录的权限可以确保只有授权的用户能够读取、写入或执行这些文件和目录。 本文将详细介绍如何在Linux系统中更改文件和目录的权限。 1. 文件和目录权限概述 在Linux系统中ÿ…...

Revit楼板问题:楼板连接处以及楼板开洞,一键开洞
在我们做楼梯时,楼梯与楼板处的连接处理不是那么符合实际,会出现一些问题,如下图,这样的连接会导致楼梯配筋时钢筋外露。 我们来学习如何调节楼板与楼板连接处的高度,选中楼梯,点击“编辑楼梯”在所需要更改…...

【AI领域+餐饮】| 论ChatGPT在餐饮行业的应用展望
💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…...

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(5月29日论文合集)
文章目录 一、检测相关(12篇)1.1 Linear Object Detection in Document Images using Multiple Object Tracking1.2 Hybrid Energy Based Model in the Feature Space for Out-of-Distribution Detection1.3 BEV-IO: Enhancing Birds-Eye-View 3D Detection with Instance Occu…...

Altium Designer 相同电路多组复制布线
在进行设计开发的时候,总会遇到相同的电路,或者模块,这些电路可以使用相同的布局和走线。我们可以画好其中一部分,然后直接复制,就可以提高效率。下面记录我自己的实际操作过程,有一些地方遇到了问题&#…...

C++线程池介绍和C++代码实现
1、介绍 1.1 线程池应用场景 在进行创建线程任务时,如果需要频繁的创建线程、销毁线程,这样会极大地降低效率,因为创建线程也是需要时间的,一个完整的线程处理运行时间包括:线程的创建时间、线程运作时间、线程的销毁…...

【day 06】vue的组件
组件 组件就是把一个网页分割成独立的小的模块,然后通过把模块进行组合,构建成一个大型的应用 单文件组件 只有一个组件 html css js 都在这个文件内 非单文件组件 可有多个组件 全局注册 !! 得先注册子组件 再生成 vm实例对象 创建子组件 const …...

第3章 Class and Object
构造函数 Guaranteed initialization with the constructor使用构造函数保证初始化 • If a class has a constructor, the compiler automatically calls that constructor at the point an object is created, before client programmers can get their hands on the o…...

卫星定位北斗芯片AT6558一款高性能BDS/GNSS多模卫星导航接收机SOC单芯片
1 芯片简介 AT6558R是一款高性能BDS/GNSS多模卫星导航接收机SOC单芯片,片上集成射频前端, 数字基带处理器,32位的RISCCPU,电源管理功能。 芯片支持多种卫星导航系统,包括中国的北斗卫星导航系统BDS,美国的GPS,俄罗斯 的…...

提升您的 MQTT 云服务:深入探索 BYOC
引言 您是否希望将物联网基础设施提升到更高的水平?为了应对业务的不断扩展,您需要一个强大且安全的消息平台来支持它。 MQTT 协议凭借其轻量级、发布/订阅模型和可靠性,已经成为构建物联网平台的首选方案。但是,随着业务的增长…...
Zookeeper面试题总结
1、说说 Zookeeper 是什么? 有些软件你想做成集群或者分布式,你可以用 ZooKeeper 帮你来辅助实现。特点:ZooKeeper 的特点:维护、协调、管理、监控 最终一致性:客户端看到的数据最终是一致的。可靠性:服务…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...