单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号
一,简介
一般来说,公司有很多系统使用,为了实现统一的用户名管理和登录所有系统(如 GitLab、Harbor 等),并在员工离职时只需删除一个主账号即可实现权限清除,可以采用 单点登录 (SSO) 和 集中式身份认证 系统。以下工具都可使用。
Keycloak(开源,功能强大且易于部署)
Okta/Auth0(商业化解决方案,支持更多高级功能)
LDAP(轻量级目录访问协议,可搭配 FreeIPA)
Casdoor (轻量级的身份认证和授权平台)
上面试用了keycloak和casdoor,keycloak配置复杂,而且界面不是很友好,所以选择了Casdoor。
casdoor用他们的云需要付费,自己服务器搭建则免费,所以这里自建就行了。
Casdoor是一款轻量级的身份认证和授权平台,支持多种协议(OIDC、OAuth2、SAML、CAS 等),并提供了简单易用的界面和丰富的功能。主要有以下特点:
1,,多协议支持
支持 OIDC、OAuth2、SAML、CAS 等协议,可以适配不同的应用系统。
支持单点登录(SSO),登录一次即可访问多个系统。
2,集中用户管理
提供用户增删改查功能,支持直接管理用户账户。
支持与 LDAP 集成,实现统一的用户信息管理。
3,权限控制
支持角色权限管理,可以为用户分配不同的权限和角色。
删除用户后,其在其他系统中的访问权限也会被移除。
4,易集成
提供 SDK 和 API,可以轻松集成到 GitLab、Jenkins、Harbor 等支持标准协议的系统中。
5,支持多种登录方式
支持密码登录、短信/邮件验证码登录,以及社交登录(如 Google、GitHub 等)。
满足企业和用户对灵活认证方式的需求。
如果公司有现成的LDAP使用,或者比较老的系统,可以使用Casdoor+LDAP方式,可以同步至casdoor集中管理。
二,Casdoor搭建
casdoor支持多语言,界面语言支持都非常友好,看文档也不费力,这也是选择它的一个重要原因。
这里测试,用最简单的docker搭建即可。生成环境建议其他正式安装方式。
创建文件夹,将配置文件挂载到此文件夹,便于配置。
官方配置文件下载:https://github.com/casdoor/casdoor/blob/master/conf/app.conf
mkdir /casdoor
cd /casdoor
vim app.conf
最后启动
docker run -d -p 8000:8000 -v /root/casdoor:/conf casbin/casdoor-all-in-one
由于与gitlab集成,必须需要SSL证书,所以用nginx反代绑定域名操作,这里示例casdoor.ywbj.cc
登录网站,默认账号密码admin 123
三,Casdoor基本使用
1,组织用户管理
用户管理,只有一个默认系统组织 built-in,这里新建一个公司组织company,便于管理。
company下,创建一个开发群组develop。
群组下有一个用户zhangsan(组织下有应用时才可以创建)
2,应用管理
在‘身份认证’的‘应用’,里面,默认有一个应用app-built-in,主要功能是登录casdoor自己系统的。
目前此应用默认只有 默认组织 built-in 可以登录。其他不在此组织的用户登录都无法登录。
如果创建新组织新用户,需要登录casdoor,就还需要修改一下配置。
编辑默认应用,在组织选择模式,选择 “选择”或者“输入”,都可以。
再次打开页面,可以选择组织,如这里测试的zhangsan只有选择company后,才能登录。
四,创建应用集成gitlab
1,casdoor创建应用
官网有集成说明文档,也可以参考:https://casdoor.org/zh/docs/integration/ruby/gitlab
在应用里面创建一个新的应用,用于gitlab集成。我这里gitlab测试网址为:gitlab.ywbj.cc
填写主要的信息就2个,组织选择company
重定向url,根据自己gitlab网址来写,这里示例为:
https://gitlab.ywbj.cc/users/auth/openid_connect/callback
记下ID和密钥,在gitlab配置需要用到。
2,gitlab配置
在gitlab服务器,修改配置文件
vi /etc/gitlab/gitlab.rb
在OmniA添加配置,当然在可以任何地方都可以添加,我添加这里便于管理。
将casdoor的ID和密钥,url写入即可。
gitlab_rails['gitlab_username_changing_enabled'] = false
gitlab_rails['omniauth_auto_link_user'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']
gitlab_rails['omniauth_block_auto_created_users'] = false gitlab_rails['omniauth_providers'] = [ { name: "openid_connect", label: "Casdoor", # 可选的登录按钮标签,默认为 "Openid Connect" args: { name: "openid_connect", scope: ["openid", "profile", "email"], response_type: "code", issuer: "https://casdoor.ywbj.cc", client_auth_method: "query", discovery: true, verify_ssl: false, uid_field: "preferred_username", client_options: { identifier: "8f14334a3bd68bf336a9", secret: "9dd1b27f0e1a30226d01385c73b5aabdfd4a91bd", redirect_uri: "https://gitlab.ywbj.cc/users/auth/openid_connect/callback"} } }
]
配置文件说明,官方说明没有以下配置,需要加上去,否则登录失败报错:Signing in using your Casdoor account without a pre-existing account in gitlab.example.com is not allowed.
原因GitLab 不允许通过 Casdoor 登录的用户自动创建 GitLab 账户。这是 GitLab 的默认行为,因为 OpenID Connect 登录要求用户账户在 GitLab 中事先存在。
#为了账号名称统一管理,禁止用户更改登录用户名。默认用户可以更改自己的用户名。
gitlab_rails['gitlab_username_changing_enabled'] = false#omniauth_auto_link_user: 自动链接现有 GitLab 账户(如果 email 匹配)。
gitlab_rails['omniauth_auto_link_user'] = true#omniauth_allow_single_sign_on: 允许通过 OpenID Connect 登录自动创建账户。
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']#omniauth_block_auto_created_users: 设置为 false,允许自动创建的账户默认启用。
gitlab_rails['omniauth_block_auto_created_users'] = false
配置完成后,重新加载配置
gitlab-ctl reconfigure
3,登录测试
在casdoor 的用户管理,创建一个用户,组织company,应用选择刚才创建的gitlab。
然后登录,可以看到gitlab应用。
点击应用跳转,或者直接打开gitlab.ywbj.cc 登录界面,可以直接使用casdoor用户登录。
点击casdoor,可以直接点击登录,或者输入casdoor账号密码登录即可。
登录成功后,gitlab会自动创建同样的名称的账号,账号集成完成。
五,webhook自动删除锁定用户
上面集成了成功创建了gitlab账号,但是在casdoor删除用户时,gitlab是不会单独删除的,gitlab有自己的用户数据库。
所以这时需要搭建一个中间服务,用于检测casdoor操作并传送到gitlab执行。
casdoor支持webhook,可以检测并发送到其他api的执行。
这里检测两个动作,一个封锁或解封用户,一个删除用户。
1,创建中间服务
要实现真正的全自动化并且灵活、安全、可扩展,最佳选择仍然是使用一个中间服务器。
中间服务器的实现方式,可以参考以下实现方案:
技术选型:
语言:Python(Flask/FastAPI)、Node.js(Express)、Go 等都可以。
部署:可以运行在 Docker 容器中,方便与现有系统集成。
这里选用python的flask搭建。
首先在gitlab使用管理员创建一个访问令牌token,权限为api和sudo权限。
python安装flask,编辑中间服务。
pip install flask
vim wehook.py
最后完整代码如下:
from flask import Flask, request, jsonify
import requests
import json
import loggingapp = Flask(__name__)# 设置日志
logging.basicConfig(filename='webhook.log',level=logging.INFO,format='%(asctime)s %(levelname)s: %(message)s'
)GITLAB_API_URL = "https://gitlab.ywbj.cc/api/v4"
GITLAB_ACCESS_TOKEN = "glpat-CQk9oDfm-Dcz3f9NHojw"@app.route('/casdoor-webhook', methods=['POST'])
def handle_webhook():# 记录请求内容logging.info("Headers: %s", request.headers)# Step 1: 解析 Webhook 数据data = request.data.decode('utf-8')try:json_data = json.loads(data)except json.JSONDecodeError:logging.error("Invalid JSON payload")return jsonify({"error": "Invalid JSON payload"}), 400#logging.info("Parsed JSON: %s", json_data)if json_data.get("action") == "update-user":object_data = json.loads(json_data["object"])name = object_data.get('name')email = object_data.get("email")is_forbidden = object_data.get("isForbidden", False)logging.info('Processing update-user for name: %s, email: %s, isForbidden: %s', name, email, is_forbidden)# Step 3: 在 GitLab 中查找用户 IDresponse = requests.get(f"{GITLAB_API_URL}/users?search={name}",headers={"Authorization": f"Bearer {GITLAB_ACCESS_TOKEN}"})users = response.json()if not users or len(users) == 0:logging.warning("User not found in GitLab: %s", name)return jsonify({"error": "User not found"}), 404user_id = users[0]["id"]# Step 4: 根据 isForbidden 状态封锁或解封用户if is_forbidden:block_response = requests.post(f"{GITLAB_API_URL}/users/{user_id}/block",headers={"Authorization": f"Bearer {GITLAB_ACCESS_TOKEN}"})logger.info("Block user response: %s", block_response.status_code)if block_response.status_code == 201:logger.info("User blocked successfully: %s", name)return jsonify({"message": "User blocked successfully"}), 200else:logger.error("Failed to block user: %s", name)return jsonify({"error": "Failed to block user"}), 500else:unblock_response = requests.post(f"{GITLAB_API_URL}/users/{user_id}/unblock",headers={"Authorization": f"Bearer {GITLAB_ACCESS_TOKEN}"})logger.info("Unblock user response: %s", unblock_response.status_code)if unblock_response.status_code == 201:logger.info("User unblocked successfully: %s", name)return jsonify({"message": "User unblocked successfully"}), 200else:logger.error("Failed to unblock user: %s", name)return jsonify({"error": "Failed to unblock user"}), 500if json_data.get("action") == "delete-user":object_data = json.loads(json_data["object"])name = object_data.get('name')email = object_data.get("email")logging.info('Processing delete-user for name: %s, email: %s', name, email)# Step 3: 在 GitLab 中查找用户 IDresponse = requests.get(f"{GITLAB_API_URL}/users?search={name}",headers={"Authorization": f"Bearer {GITLAB_ACCESS_TOKEN}"})#logging.info("GitLab search response: %s", response.json())users = response.json()if not users or len(users) == 0:logging.warning("User not found in GitLab: %s", name)return jsonify({"error": "User not found"}), 404user_id = users[0]["id"]# Step 4: 删除用户delete_response = requests.delete(f"{GITLAB_API_URL}/users/{user_id}",headers={"Authorization": f"Bearer {GITLAB_ACCESS_TOKEN}"})if delete_response.status_code == 204:logging.info("User deleted successfully: %s", name)return jsonify({"message": "User deleted successfully"}), 200else:logging.error("Failed to delete user: %s", name)return jsonify({"error": "Failed to delete user"}), 500logging.warning("Invalid action: %s", json_data.get("action"))return jsonify({"error": "Invalid action"}), 400if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)
最后运行即可测试。
python wehook.py
2,创建webhook
组织同样使用company。
链接:需要传给中间服务api的链接。
我这里用了nginx反代监听5000端口,使用域名https://webhook.ywbj.cc/casdoor-webhook作为api链接。
事件:检测update-user,delete-user两个动作,用于检测封锁还是删除用户。
3,casdoor封锁删除用户测试
在casdoor用户管理,编辑,打开被禁用,保存退出。
在gitlab管理员查看用户
同样,直接删除casdoor的用户,gitlab也直接删除。
在日志文件查看日志,也可以看到相关信息。
root@ht2024061430711:~/webhook# cat webhook.log 2024-12-19 12:59:27,133 INFO: Processing update-user for name: zhangsan, email: 1i88kf@example.com, isForbidden: True
2024-12-19 12:59:28,059 INFO: Block user response: 201
2024-12-19 12:59:28,060 INFO: User blocked successfully: zhangsan
2024-12-19 12:59:28,062 INFO: 127.0.0.1 - - [19/Dec/2024 12:59:28] "POST /casdoor-webhook HTTP/1.0" 200 -
2024-12-19 13:01:42,837 INFO: Headers: Host: webhook.ywbj.cc2024-12-19 13:01:42,839 INFO: Processing delete-user for name: zhangsan, email: 1i88kf@example.com
2024-12-19 13:01:43,328 INFO: User deleted successfully: zhangsan
2024-12-19 13:01:43,330 INFO: 127.0.0.1 - - [19/Dec/2024 13:01:43] "POST /casdoor-webhook HTTP/1.0" 200 -
六,构建docker持续运行(扩展)
以上已经实现基本功能,测试也可以直接用nohup 命令一直在后台运行。
但是便于稳定与管理,这里使用打包成docker镜像运行。
在运行flask应用时,经常看到警告
INFO: WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
表明 Flask 当前正在使用其内置开发服务器,这种服务器仅适合开发和调试环境,不推荐在生产环境中使用。要优化并适用于生产环境,可以采用 WSGI 服务器,如 Gunicorn 或 uWSGI。
所以生产环境,这里采用Gunicorn。
1,在文件夹中创建必要的文件
创建Dockerfile构建文件
# 使用官方 Python 基础镜像
FROM python:3.9-slim# 设置工作目录
WORKDIR /app# 复制当前目录到容器中
COPY . .# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt# 暴露 Flask 默认端口
EXPOSE 5000# 使用 Gunicorn 启动 Flask 应用
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "webhook:app"]
Gunicorn 是一种高性能的 WSGI HTTP 服务器,适合生产环境,性能更稳定,支持多线程和多进程。
如果需要更高的性能,还可以调整 Gunicorn 参数,例如指定工作进程数和线程数:
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "3", "--threads", "2", "webhook:app"]
创建一个 requirements.txt 文件,用于存放 Python 依赖。内容如下:
flask
requests
gunicorn
创建一个 .dockerignore 文件,避免将不必要的文件复制到镜像中:
__pycache__/
*.pyc
*.log
*.txt~
*.git
2,重新配置日志持久化
修改代码,确保日志写入到特定路径,例如 ./logs/webhook.log:
用于挂载日志文件到宿主机。
# 确保日志路径
log_file_path = "./logs/webhook.log"# 创建日志记录器
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.propagate = False# 添加文件日志
file_handler = logging.FileHandler(log_file_path)
file_handler.setLevel(logging.INFO)
file_formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s")
file_handler.setFormatter(file_formatter)# 添加控制台日志
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s")
stream_handler.setFormatter(stream_formatter)# 将日志处理器添加到记录器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)logger.info("Webhook server started. Logging initialized.")
后面loggin.info全部修改为logger.info即可
3,构建和运行 Docker 容器
#构建镜像
docker build -t flask-webhook .
#运行服务
docker run -d --restart unless-stopped --name flask-webhook -p 5000:5000 -v ./logs:/app/logs flask-webhook
查看服务并测试
root@ht2024061430711:~/webhook# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ffe0b07f6f7 flask-webhook "gunicorn --bind 0.0…" 3 minutes ago Up 3 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp flask-webhook
运行后查看日志
root@ht2024061430711:~/webhook# cat logs/webhook.log
2024-12-19 15:36:38,991 INFO: Webhook server started. Logging initialized.
2024-12-19 15:36:38,991 INFO: Webhook server started. Logging initialized.
2024-12-19 07:53:26,415 INFO: Processing update-user for name: laowang, email: 1ul3ev@example.com, isForbidden: False
2024-12-19 07:53:27,171 INFO: Unblock user response: 201
2024-12-19 07:53:27,171 INFO: User unblocked successfully: laowang
2024-12-19 07:53:48,163 INFO: Headers: Host: webhook.ywbj.cc2024-12-19 07:53:48,166 INFO: Processing delete-user for name: laowang, email: 1ul3ev@example.com
2024-12-19 07:53:48,583 INFO: User deleted successfully: laowang
运行正常。
下一步集成其他系统账号,有时间在更新。
相关文章:

单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号
一,简介 一般来说,公司有很多系统使用,为了实现统一的用户名管理和登录所有系统(如 GitLab、Harbor 等),并在员工离职时只需删除一个主账号即可实现权限清除,可以采用 单点登录 (SSO) 和 集中式…...

PaddlePaddle飞桨Linux系统Docker版安装
PaddlePaddle飞桨Linux系统Docker版安装 最近学习和了解PP飞桨,一切从安装开始。官网的安装教程很详细: https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/docker/linux-docker.html 记录我在安装过程中遇到的问题…...

一款基于.NET开发的简易高效的文件转换器
前言 今天大姚给大家分享一款基于.NET开发的免费(GPL-3.0 license)、简易、高效的文件转换器,允许用户通过Windows资源管理器的上下文菜单来转换和压缩一个或多个文件:FileConverter。 使用技术栈 ffmpeg:作为文件转换…...

Spring Boot教程之三十一:入门 Web
Spring Boot – 入门 Web 如今,大多数应用程序都需要模型-视图-控制器(MVC) 架构来满足各种需求,例如处理用户数据、提高应用程序效率、为应用程序提供动态特性。它主要用于构建桌面图形用户界面 (GUI),但现在越来越流行用于构建基于 Web 的…...

青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试 一、单元测试(Unit Testing)二、集成测试(Integration Testing)三、区别四、Go Web单元测试使用testing包使用testify框架使用GoConvey框架 五、应用示例步骤 1: 创建HTT…...

概率论 期末 笔记
第一章 随机事件及其概率 利用“四大公式”求事件概率 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量(R.V)求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续型分布的计算 均匀分布 正态…...

Typesense:开源的高速搜索引擎
在当今数据驱动的世界中,高效、快速且智能的搜索能力是任何应用程序和网站成功的关键因素之一。无论是电商平台、内容管理系统还是社交媒体,用户都希望能够迅速找到所需信息。Typesense,作为一款优秀的开源搜索引擎,旨在通过其卓越…...

【vue】圆环呼吸灯闪烁效果(模拟扭蛋机出口处灯光)
效果图先发: 页面部分: <div ref"round" class"round"><div class"light" ref"light"/><div class"box"></div></div>js部分(控制圆环生成); setRound…...

飞牛 fnos 使用docker部署 Watchtower 自动更新 Docker 容器
Watchtower 简介 Watchtower 是一款开源的 Docker 容器管理工具,主要功能为自动更新运行中的 Docker 容器,支持自动拉取镜像并更新容器、配置邮件通知以及定时执行容器更新任务。 用 compose 搭建 Watchtower 的步骤 新建文件夹:在任意位置…...

《信管通低代码信息管理系统开发平台》Linux环境安装说明
1 简介 信管通低代码信息管理系统应用平台提供多环境软件产品开发服务,包括单机、局域网和互联网。我们专注于适用国产硬件和操作系统应用软件开发应用。为事业单位和企业提供行业软件定制开发,满足其独特需求。无论是简单的应用还是复杂的系统ÿ…...

基于物联网的车辆定位和防盗报警系统(论文+源码)
1 系统概述 本文的主要内容是设计一个基于物联网的车辆定位和防盗报警系统,主要是利用STC89C52单片机来作为整体的核心控制元件,主要的核心控制模块主要由GSM通信模块,GPS定位模块,热释电红外检测模块,报警模块以及其他…...

京东零售数据可视化平台产品实践与思考
导读 本次分享题目为京东零售数据可视化平台产品实践与思考。 主要包括以下四个部分: 1. 平台产品能力介绍 2. 业务赋能案例分享 3. 平台建设挑战与展望 作者:梁臣 京东 数据产品架构师 01平台产品能力介绍 1. 产品矩阵 数据可视化产品是一种利用…...

Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
第一步,public文件夹下新建static文件夹存放静态资源 我存放了一个 .docx文件,当然,你可以存放pdf/word 等文件都可以。 第二步,模拟a标签下载 //html部分<el-button type"primary" plain click"download&quo…...

ensp 基于EASY IP的公司出口链路配置
Easy IP Easy IP技术是NAPT的一种简化情况。Easy IP无须建立公网IP地址资源池,因为Easy IP只会用到一个公网IP地址,该IP地址就是路由器R连接公网的出口IP地址。Easy IP也会建立并维护一张动态地址及端口映射表,并且Easy IP会将这张表中的公网…...

方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]
文章目录 方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利…...

零知识证明:区块链隐私保护的变革力量
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...

解决:el-select可输入时失焦会失去输入框中值
1、展示部分 <template><el-select v-model"addForm.companyName" filterable placeholder"请输入/选择公司名称" :loading"loading":filter-method"(value) > dataFilter(value)" change"selectCompany">&…...

ollama-webui - Ollama的ChatGPT 风格的 Web 界面
更多AI开源软件: 发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - :发现分享好用的AI工具、AI开源软件、AI模型。收录了AI搜索引擎,AI绘画工具、AI对话聊天、AI音频工具、AI图片工具、AI视频工具、AI内容检测、AI法律助手、AI高考、AI志…...

「下载」智慧产业园区-数字孪生建设解决方案:重构产业全景图,打造虚实结合的园区数字化底座
数字孪生技术作为一种创新的管理工具,正逐步展现出其在智慧园区建设中的重要意义。以下将从几个方面详细阐述数字孪生在智慧园区建设中的关键作用。 一、提升园区运营管理的智能化水平 数字孪生技术通过构建园区的虚拟镜像,实现了对园区物理世界的全面…...

使用Grafana中按钮插件实现收发HTTP请求
最近项目中需要监控分布式集群的各项指标信息,需要用到PrometheusGrafana的技术栈实现对分布式集群的各个节点状态进行可视化显示,但是要求前端需要提供一个易用的接口让用户可以触发一些操作,例如负载高时进行负载均衡或弹性伸缩。网上找到的…...

【附源码】Electron Windows桌面壁纸开发中的 CommonJS 和 ES Module 引入问题以及 Webpack 如何处理这种兼容
背景 在尝试让 ChatGPT 自动开发一个桌面壁纸更改的功能时,发现引入了一个 wallpaper 库,这个库的入口文件是 index.js,但是 package.json 文件下的 type:"module",这样造成了无论你使用 import from 还是 require&…...

Elasticsearch介绍及安装部署
Elasticsearch介绍 Elasticsearch 是一个分布式搜索引擎,底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节,提供了分布式特性,同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户,被用在网站…...

物理层知识要点
文章目录 物理层接口的四大特性通信基础编码和调制(1)数字数据编码为数字信号(2)模拟数据编码为数字信号(3)常见调制方式(3)信道的极限容量 多路复用技术数据传输方式物理层下的传输…...

SpringBoot 自动装配原理及源码解析
目录 一、引言 二、什么是 Spring Boot 的自动装配 三、自动装配的核心注解解析 3.1 SpringBootApplication 注解 (1)SpringBootConfiguration: (2)EnableAutoConfiguration: (3…...

Craft CMS 模板注入导致 Rce漏洞复现(CVE-2024-56145)(附脚本)
0x01 产品描述: Craft CMS 是一个灵活且强大的内容管理系统(CMS),专为创意团队和开发人员设计,提供高度可定制、直观且性能优越的网站和内容管理解决方案。它以用户友好的界面、强大的插件生态系统以及支持现代web开发最佳实践的特性而闻名0x02 漏洞描述: 由于模板…...

Next.js 新手容易犯的错误 _ 加载与缓存管理的关键(5)
1 错误地处理搜索参数(Search Params) 问题是什么? 在 Next.js 中,搜索参数指的是 URL 中用 ?keyvalue 表示的部分,比如 https://example.com/products?colorred 中的 colorred。这通常用于过滤、排序或选择某些选…...

/etc/fstab 文件学习systemd与该文件关系
文章目录 一、文件字段1.1、设备标识1.2、挂载点1.3、文件系统类型1.4、挂载选项1.5、dump1.5、fsck顺序 二、/etc/fstab 与systemd 的关系2.1、/etc/fstab 与systemd 的关系2.2、systemd 之前/etc/fstab生效过程2.3、systemd 时代/etc/fstab生效过程 三、相关知识3.1、如何更具…...

从源码分析swift GCD_DispatchGroup
前言: 最近在写需求的时候用到了DispatchGroup,一直没有深入去学习,既然遇到了那么就总结下吧。。。。 基本介绍: 任务组(DispatchGroup) DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…...

25计软新增考研院校!或可捡漏上岸!
C哥专业提供——计软考研院校选择分析专业课备考指南规划 新增的计算机与软件工程考研院校为考研同学带来了多方面的机遇,这些机遇不仅体现在过国家线后可能面临的更低竞争压力,还包括更多元化的教育选择和更广阔的就业前景: 一、降低竞争压…...

C# 线程安全集合
文章目录 引言一、ConcurrentBag<T>二、ConcurrentQueue<T>三、ConcurrentStack<T>四、ConcurrentDictionary<TKey, TValue>五、总结引言 在多线程编程环境中,多个线程可能同时访问和操作集合数据。如果使用普通集合,很容易引发数据不一致、错误结果…...