阿尔法色色之屋
type: channel
link: https://www.alphah.top/
description: 阿尔法色色之屋
items: 【vate】Docker安装MySQL及备份
items: 【vate】N355 核显配置以及硬件加速
items: 2024.07.19 心「秦亚」
items: 2024.07.04 语「音乐之路」
items: 【vate】把 Jellyfin 更新消息推送到QQ
items: 【vate】计算机二级练习留档
items: 【vate】常用六大排序算法的实现
items: 【vate】手把手教你在 Debian/Ubuntu 上二进制安装MySQL
items: 【秦亚の玩具屋】慢玩系列 铁三角 EXE - PUNI 1000 - 柔软款 测评
items: 【Spring】Spring Security 入门原理及实战

【vate】Docker安装MySQL及备份
type: item
date: 2025-05-31T18:22:51+08:00
description: 文章首发vate，授权alphaH转载。转载需标明出处，禁止未经授权转载。MySQL容器创建现在推荐MySQL8.4 LTSC版本docker compose 文件现在不需要version声明了docker compose 文件services: mysql-db: # 指定容器的名称 container_name: mysql # 指定镜像和版本 image: mysql:8.0 ports: - "3306:3306" restart: always # 容器日志大小配置 logging: driver: 'json-file' options: max-size: '5g' environment: # 配置root密码 MYSQL_ROOT_PASSWORD: PASSWORD volumes: # 挂载数据目录 - "./data:/var/lib/mysql" # 挂载配置文件目录 - "./config:/etc/mysql/conf.d" MySQL 用户权限因为要从容器外面连入，所以MySQL用户的host不能为localhost。权限不推荐照搬，建议最小权限原则，只提供需要的权限就好-- 登入容器 docker exec -it mysql mysql -u username -p CREATE USER 'user1'@'%' IDENTIFIED BY 'password'; ALTER USER 'user1'@'%' IDENTIFIED BY 'password'; -- 授予备份权限 -- GRANT PROCESS ON *.* TO `user1`@`%`; -- 刷新权限 FLUSH PRIVILEGES; -- 权限太大不建议使用： --- GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; -- 如果已存在其他 host 的 root 用户，可以复制权限 -- GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' AS 'root'@'localhost'; MySQL数据导入如果有需要，要提前创建数据库-- 登入容器 docker exec -it mysql_container_name mysql -u username -p mysql> create database database_name注入数据docker exec -i mysql mysql -uroot -p'PASSWORD' database_name < ./data.sqlMySQL数据备份用 crontab 创建定时计划# crontab -e 0 6 * * * /usr/bin/docker exec mysql mysqldump -uroot -p'PASSWORD' --no-tablespaces database_name > "/mysqlbk/$(date +\%Y\%m\%d_\%H\%M\%S).sql"根据官方文档说明，如果命令带--no-tablespaces 就不需要使用PROCESS 权限https://dev.mysql.com/doc/refman/8.4/en/mysqldump.htmlmysqldump requires at least the SELECT privilege for dumped tables, SHOW VIEW for dumped views, TRIGGER for dumped triggers, LOCK TABLES if the --single-transaction option is not used, PROCESS if the --no-tablespaces option is not used, and the RELOAD or FLUSH_TABLES privilege with --single-transaction if both gtid_mode=ON and gtid_purged=ON|AUTO. Certain options might require other privileges as noted in the option descriptions.

【vate】N355 核显配置以及硬件加速
type: item
date: 2025-05-12T16:09:00+08:00
description: 文章首发 vate，授权 阿尔法色色之屋 转载。转载需标明出处，禁止未经授权转载。买了个N355，装了最新的Debian12.10，发现无法调用核显，发现是Linux内核太低了用不了。# lspci -nn |grep VGA 00:02.0 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [Intel Graphics] [8086:46d3]定位问题安装官网说，要先查看设备的id，然后才能确定需要的内核版本https://dgpu-docs.intel.com/driver/client/overview.html#ubuntu-22.04英特尔再这个页面提供的是Ubuntu的软件包，debian用不了，PAA源加不上解决PAA报错 apt-get install python3-launchpadlib https://askubuntu.com/questions/1480616/adding-opencpn-repository-attributeerror-nonetype-object-has-no-attribute经查询要内核版本最低为：46d3 ，对应6.13# lspci -nn |grep VGA 00:02.0 VGA compatible controller [0300]: Intel Corporation Alder Lake-N [Intel Graphics] [8086:46d3]寻找解决办法debian官方的内核版本较低，得尝试使用其他方式升级内核。查找 debian 官网，查看内核的更新计划。发现目前debian12.10（最新）的系统默认内核是6.1，最高能用apt升级到6.12版本。包括还没发布的debian13 也是时候Linux 6.12 内核。但是核显要求Linux内核最低6.13https://www.debian.org/releases/testing/release-notes/whats-new.zh_CN.html如图46d3对应的是6.13内核解决问题找朋友求助（感谢朋友），经过搜索最后决定用xanmod对内核进行升级https://xanmod.org/顺利的话只要图片上的三个步骤就能完成安装了。N355在内的N系列处理器现在都是 Intel 12th Gen (Alder Lake) 架构。twin 架构算在alder架构里apt升级报错之前乱装驱动，导致apt升级内核的时候报错，解决办法是把报错的软件用apt删了就好。我这里是多装了给intel-i915-dkms的包drivers/misc/mei/pxp/mei_pxp.o: warning: objtool: init_module(): not an indirect call target drivers/misc/mei/pxp/mei_pxp.o: warning: objtool: cleanup_module(): not an indirect call target In file included from /var/lib/dkms/intel-i915-dkms/1.25.1.17.250113.16/build/backport-include/linux/moduleparam.h:29, from /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/linux/module.h:22, from /var/lib/dkms/intel-i915-dkms/1.25.1.17.250113.16/build/backport-include/linux/module.h:3, from drivers/vfio/pci/i915/main.c:9: drivers/vfio/pci/i915/main.c:440:18: error: expected ‘,’ or ‘;’ before ‘I915’ 440 | MODULE_IMPORT_NS(I915); | ^~~~ /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/linux/moduleparam.h:26:61: note: in definition of macro ‘__MODULE_INFO’ 26 | = __MODULE_INFO_PREFIX __stringify(tag) "=" info | ^~~~ /usr/src/linux-headers-6.14.6-x64v3-xanmod1/include/l…

2024.07.19 心「秦亚」
type: item
date: 2024-07-19T18:15:00+08:00
description: 夜幕降下，脑内再一次拨弄着朦胧的意识。熟悉的场景、熟悉的思绪，涌上心头。曾经习以为常的风景，在这里多了一抹新奇。那是谁？会是谁？将是谁？流落在现实中的「我」啊，内心孤寂的角落，渴望奇迹降临。驻足在梦境中的「我」啊，世界孤寂的各处，渴望与人相伴。两人不愿瞥开视线，想将各自的所有，印入到记忆深处。下一次再见，又会是什么时候。回望曾经见面的地点，最美的奇迹可能早已在身边。「我」，便是「我」生命中迸发的奇迹。[photo][/photo]

2024.07.04 语「音乐之路」
type: item
date: 2024-07-04T02:30:00+08:00
description: 一部伟大的作品，这首承载了10年回忆的歌曲，在现今的技术革新后重新焕发了生机。重音Teto曾是愚人节玩笑的产物，但过程中每个人都带着不羁的畅想进行创作，反而体现出了那时候人们最纯粹的想象力与创造力。这也是生活在新时代的我们所逐渐丢失的东西。在AI迅猛发展的如今，人们面临着新的机遇与挑战。对过去美好回忆的执念、对当下浮躁风气的焦虑，把我们困在了一个又一个选择的交叉路口中。也许，我们不必彷徨。音乐是心灵的明灯，无关形式，无关风格，无关载体。至少于我而言，每当重音的复苏之声响起，我将不再徘徊，我将继续倾听，用这连通了过去与现在的歌声，向着未来骄傲地前行！[timeline-item] [btn href="http://www.bilibili.com/video/BV1Fh4y1J721" type="default"]bilibili原视频地址[/btn] [/timeline-item][dplayer src="https://oss.alphah.top/Dream/2024.07.04.mp4"/]

【vate】把 Jellyfin 更新消息推送到QQ
type: item
date: 2024-06-10T12:02:00+08:00
description: 思路让 Jellyfin 使用 LLOneBot onebot-11 协议的API接口，把更新推送到QQ。在部署好支持OneBot协议的的QQ机器人后，就已经具备收发QQ消息的能力了。一. 调用 onebot-11 API先把 LLOneBot 部署好，Linux 无 GUI 可以用 NapCatQQ项目。设置API端口打开HTTP服务，并设置端口LLOneBot 设置方法：NapCatQQ 设置方法：{ "httpHost": "", "enableHttp": false, "httpPort": 3000, ............略.................... } 测试API浏览器访问下面的连接，就可以测试消息是否能正常发送：需要保证端口，和上一步设置的端口一致send_group_msg , send_group_msg 顾名思义分别对应私聊消息和群聊消息#群聊消息 http://127.0.0.1:3000/send_group_msg?group_id=群号&message="hello"&auto_escape=false #私聊消息： http://127.0.0.1:3000/send_private_msg?user_id=QQ号&message="hello"&auto_escape=false有条件的，可以构造POST请求进行测试：#私聊消息： curl -X POST "http://127.0.0.1:3000/send_private_msg" \ -H "Content-Type: application/json" \ -d '{ "user_id": QQ号, "message": "hello post json" }' #群聊消息 curl -X POST "http://127.0.0.1:3000/send_group_msg" \ -H "Content-Type: application/json" \ -d '{ "group_id": 群号, "message": "hello post json" }'二. 设置 Jellyfin webhook 插件先安装好Webhook插件，并点击进行设置在Server Url里输入jellyfin服务的访问地址，然后点击 Add Generic Destination名字自己随便取，Url 需要注意一下，私聊消息接口用: send_private_msg 群聊用: send_group_msgItem Type 默认是全选，可以根据自己需要进行勾选在最下方 Template空白处填入指定代码，最后在点save就大功告成了注：私聊消息用到是user_id，并填写qq号。群聊要改成group_id {{#if_equals NotificationType 'ItemAdded'}} { "user_id": qq号, "message": "{{{SeriesName}}} 更新拉！\n[CQ:image,file={{ServerUrl}}/Items/{{SeasonId}}/Images/Primary]\n{{#if_equals ItemType 'Episode'}}S{{SeasonNumber00}}E{{EpisodeNumber00}} {{{Name}}}\n{{else}}名称：{{{Name}}} ({{Year}})\n{{/if_equals}}时长：{{RunTime}}" } {{/if_equals}}三. 结果演示：小提示：jellyfin 的推送不是实时的，最好在定时任务里把 “扫描媒体库”开了。

【vate】计算机二级练习留档
type: item
date: 2023-08-25T17:36:00+08:00
description: 前言：之前做算法复建时写的，写道比较拉，黑历史.....具体题目信息在网站上，懒得拷贝了https://www.dotcpp.com/oj/train/1002/no1平均值计算// no1-average.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <stdio.h> int main() { int a[9], sum = 0,b=0; for (int i = 0; i < 10; i++) { scanf("%d", &a[i]); sum += a[i]; } float ave = sum / 10; for (int i = 0; i < 10; i++) if (a[i] > ave) { b++; } printf("%d", b); } no2计算素数和#include<stdio.h> #include<math.h> bool isprime(int x) { if (x<=3) { return x > 1; } if (x%6!=1&&x%6!=5) { return false; } for (int i = 5; i <=sqrt(x) ; i+=6) { if (x%i==0||x%(i+2)==0) { return false; } } return true; } int main(){ int n, m,ans=0; scanf("%d%d",&m,&n); for (int i = m; i <=n; i++) { if (isprime(i)) ans += i; } printf("%d",ans); return 0; } no3公约公倍#include<stdio.h> #pragma warning (disable: 4996) int f(int min, int max) { if (max%min==0) { return min; } else { f(max % min, min); } } int main() { int m, n; int max, min; int a, b; scanf("%d%d", &m, &n); if (m>n) { max = m; min = n; } else { max = n; min = m; } a=f(min, max); b = max * min / a; printf("%d\n%d",a,b); return 0; }no4温度转换#include<stdio.h> int main() { float a, b; scanf("%f", &a); b = 5 * (a - 32)/9; printf("%.2f",b); return 0; }no5分段函数#include<stdio.h> int main() { float x,y; scanf("%f", &x); if (x<1) { y = x; } else if (x<10) { y = 2 * x - 1; } else { y = 3 * x - 11; } printf("%.2f", y); return 0; } no6求偶数和#include<stdio.h> int main() { int n, sum = 0,a; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a); if (a%2==0) { sum += a; } } printf("%d", sum); return 0; }no7等差数列#include<stdio.h> int main() { int n,sum; scanf("%d", &n); sum = (n * 2 + n * (n - 1) / 2 * 3); printf("%d", sum); return 0; }no8同因查找#include<stdio.h> int main() { for (int i = 10; i <=1000 ; i++) { if (i % (2*3*7) == 0) { printf("%d\n", i); } } return 0; }no9计负均正#include<stdio.h> int main() { int a[20], sum = 0, count = 0; double average = 0; for (int i = 0; i < 20; i++) { scanf("%d", &a[i]); if (a[i]<0) { count++; } else { sum += a[i]; } } average = (d…

【vate】常用六大排序算法的实现
type: item
date: 2023-08-25T17:15:00+08:00
description: 非原创，协会里爬的插入排序(insertion_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; // 插入排序 void insertion_sort(vector<int>& a) { for(int i=0;i<a.size();i++)// 从第一个开始做插入 { int t=a[i],j;// 存储数据 for(j=i-1;j>=0;j--)// 从前一个数开始作比较 if(t<a[j]) a[j+1]=a[j]; // 若前一个数比当前数大，则后一个数放前一个数 else break;// 否则退出 a[j+1]=t; // 后一个数放存储的数值，这个插入操作必须放在循环外面 } } int main() { int n; vector<int> a; cin>>n; for(int i=0,t;i<n;i++) { cin>>t; a.push_back(t); } insertion_sort(a); for(int i=0;i<n;i++)cout<<a[i]<<" "; return 0; }堆排序(heap_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; int n,m; vector<int> heap; // 从小到大排序建大根堆，因为根节点要放到最后面 // 从大到小排序建小根堆 //堆中，默认下标0弃置，下标1的元素为根节点 //大根堆，下沉操作 void push_down(vector<int>& heap,int size,int u) { int t=u,left=u*2,right=u*2+1; if(left<=size && heap[left]>heap[t])t=left;//不越界，并且左子树较大 if(right<=size && heap[right]>heap[t])t=right;//不越界，并且右子树较大 if(t!=u)//如果存在更大的值 { swap(heap[u],heap[t]);//交换 push_down(heap,size,t);//下沉 } } //大根堆，上浮操作 void push_up(vector<int>& heap,int u) { while(u/2 && heap[u/2]<heap[u])//如果没有越界，并且父节点更小 { swap(heap[u/2],heap[u]);//交换 u/=2;//上移 } } //堆排序 void heap_sort(vector<int>& heap,int size) { int n=size; for(int i=1;i<=n;i++)push_up(heap,i);//建堆，像插入一样、上浮 //堆排序 for(int i=1;i<=n;i++)//排序n次 { swap(heap[1],heap[size]);//将根节点（最大的数）放到最后面 size--;//数量-- push_down(heap,size,1); } } int main() { cin>>n>>m; heap.resize(n+1); for(int i=1;i<=n;i++)cin>>heap[i]; heap_sort(heap,n);//排序堆中的前n个数 for(int i=1;i<=m;i++)cout<<heap[i]<<' '; return 0; } 归并排序(merge_sort)#include<iostream> #include<algorithm> #include<vector> using namespace std; void merge_sort(vector<int>& a,int l,int r) { if(l>=r)return;//此处的=号可以解决边界问题 int mid=(l+r)/2; // 去中间值 merge_sort(a,l,mid);//递归 merge_sort(a,mid+1,r); static vector<int> st; st.clear(); int i=l,j=mid+1; while(i<=mid && j<=r)//归并 if(a[i]<a[j])st.push_back(a[i++]); else st.push_back(a[j++]); //处理剩余元素 while(i<=mid)st.push_back(a[i++]); while(j<=r)st.push_back(a[j++]); // 此处建议像如下…

【vate】手把手教你在 Debian/Ubuntu 上二进制安装MySQL
type: item
date: 2023-08-25T09:55:00+08:00
description: 时隔几个月后，又重新装了一遍 MySQL 思路比之前清晰多了。虽然还有不足之处，但比之前好多了，写个教程备忘一下。此教程已经写的尽量详细了，但读者最好还是有一点点 Linux 基础。如果想省事情，可以直接选择用包管理器一键安装。apt install mysql yum install mysql文件准备下载文件官方下载地址确认glibc 版本确保自己的 glibc 版本高于 软件包标识的版本 比如，我图里安装包的glibc 版本是2.12。那么系统的glibc必须高于 2.12。如果系统的glibc 太低就不要下了。建议换个新一点的系统，或者找旧一点的二进制包。#查看 glibc 版本 $> ldd --version#下载安装包： $> wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz解压文件#解压之前下载的MySQL二进制文件 $> tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz #文件夹名改成mysql $> mv mysql-8.0.30-linux-glibc2.12-x86_64 mysql #将下载的包移到指定目录 $> mv mysql /usr/local/mysql #打扫一下战场，把压缩包删了 $> rm -f mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz #进入刚刚解压出来的 MySQL 文件夹 $> cd /usr/local/mysql 环境准备解决依赖问题：#先进到mysql/bin目录里 $> cd /usr/local/mysql/bin #查看缺少的依赖，如果没输出就说明都不缺 $> ldd mysqld mysql | grep "not found" libnuma.so.1 => not found libtinfo.so.5 => not found我这里缺了 libnuma libtinfo 这俩个依赖，这里拿我缺少的俩个依赖举一下例子，大家要根据实际情况缺什么补什么。解决 llibnuma.so.1 缺少问题#搜索一下包 $> apt search libnuma libnuma1/stable 2.0.12-1+b1 amd64 #可以看到搜索到的包名叫libnuma1 #根据搜索到底结果安装 $> apt install libnuma1 同理：解决 libtinfo.so.5 缺少问题#没有的话就找一下包 $> apt search libtinfo libtinfo5/stable 6.2+20201114-2 amd64 libtinfo6/stable,now 6.2+20201114-2 amd64 [installed] #可以看到搜索到的包有libtinfo5 和libtinfo6 #我们缺少libtinfo.so.5 就安装 libtinfo5 apt install libtinfo5创建用户和文件目录规划要确保mysql用户有对应文件夹的权限（都放在一起是为了好找、好删，不太规范，不要学我）目录/文件作用/etc/my.cnfMySQL全局配置文件/usr/local/mysqlbasedir(MySQL主程序目录)/usr/local/mysql/data/datadirdatadir(数据目录)/usr/local/mysql/data/binlogbinary logs（顾名思义，binlog文件目录）/usr/local/mysql/data/backup备份文件目录/tmp/mysqltmpdir（临时文件目录)/usr/local/mysql/data/mysql.socksocket (socke文件地址,登录用的)/usr/local/mysql/data/error.loglog_error(错误日志)/usr/lib/systemd/system/mysqld.service存放进程守护配置文件创建mysql用户创建mysql用户组和mysql用户#创建 MySQL 用户组 $> groupadd mysql #创建 MySQL 用户 $> useradd -r -g mysql -s /bin/false -d /dev/null mysql 创建文件夹创建存数据的文件夹，并赋权！！！赋权很重要。权限不够初始化会失败#创建用来存放数据的文件夹 $> mkdir -p /usr/local/mysql/data/binlog /usr/local/mysql/data/backup /usr/l…

【秦亚の玩具屋】慢玩系列 铁三角 EXE - PUNI 1000 - 柔软款 测评
type: item
date: 2023-08-20T16:57:00+08:00
description: 一、评分预览体验： ★★★★★ 9分 慢玩铁三角之一！慢玩爱好者必玩款耐久度：★★★☆☆ 6分 软胶材质，需要悉心呵护清理：★★★★☆ 8分 需要比普通杯子多花一点时间刺激度：★☆☆☆☆ 2分 低刺激下带来的柔和包裹感通道紧度： ★★☆☆☆ 4分 可塑性很强，久而久之就变成你的形状了柔软度：★★★★★ 9分 布丁般的软糯，手感很好二、前言欢迎光临阿尔法色色之屋，我是秦亚，今天玩具屋要给大家带来的产品是来自「EXE」的「PUNI 1000 - 柔软款」，是一款对标慢玩的产品。下面就让我带大家走进PUNI酱丰韵肉感中潜藏的柔软奥秘吧。三、包装与外观「PUNI 1000」的外观参考了二次元萌系的肉感画风，微微隆起的肉感腹部十分娇嫩，两侧的臀部中间是馒头瓣的入口更是互动性十足，在外观塑造上十分到位。整体材质非常软糯，手持的时候能明显得感受到舒适的握感。重量则如产品名称所示，是1kg的大型杯子，晃动时机体随着重力肆意的游离，任人摆布。通道方面则是我个人偏爱的迷乱形肉褶，常常能让人联想到本子分镜中的阴道肉壁透视图，顶部则是有一个薄片宫颈的设计，让人体验微妙的突破感，进一步丰富体验。四、体验虽然在入手前了解到「PUNI 1000」是一款高包裹感的机体，但在我用前清洗的过程中，拿手指伸进去试探时，并没有感受到特别地紧致，让我不得怀疑是否真的具有包裹性，在我将信将疑的态度下，开始使用了起来。初次使用时，我使用的是低粘度的润滑，为的是能更多地感受褶子的触感。初次探入时，外层的两个馒头瓣先是被牛牛非常轻松地顶开，随后就像是有生命力般地将牛牛向内包含进来。进入通道后，可以明显地感受到一种有别于其他慢玩通道的柔和包裹感，在过程中能明显感受到周边褶子肉粒带来的别致触感，同时顶部的薄片宫颈也恰到好处地起到了适度刺激的作用。随着时间的流逝，我的疑虑也愈发消散了。在进一步使用后，我大胆地加大了使用力度、速度和幅度，这也让我有了新的体验。随着速度的加快，机体外部的反馈也会越来越强烈，机体臀部胶体与肉体的拍打声和其有节奏的晃动都让人有了享受通道以外的乐趣，可玩性非常强，让我不由得暗自惊叹，原来杯子也能体验到臀模的冲撞快感。接着让我惊讶的便是，在如此剧烈的运动下，刺激度竟依旧能保持在一个让人舒适的水平上以至于不让人过快缴械，可能这就是慢玩的魅力。事后清洗干燥方面会要多花一点时间，需要留意处理不规则的通道、宫颈周边和宫腔内部的水渍。总结一下，大克重下带来的包裹感和柔软材质下的触感让这次「PUNI 1000」初体验十分全面且舒适，事后真的给我了一种澄澈的清爽感。五、总结非常优秀的慢玩机体，归类为慢玩铁三角之一，实至名归。润滑上我推荐使用低粘度的水基润滑，来更多的感受褶子肉粒的抚摸。另外推荐各位在使用该机体的时候大胆观看素材，以前在与杯友交流过程中得知：在使用机体时观看素材比不观看素材时的使用时长要短，这是因为视觉与触觉的双重刺激下，让人更加容易放松从而更快缴械，而「PUNI 1000 - 柔软款」则是在你观看素材的情况下使用反而会更加激起你的使用兴致与体验，体验一把本子男主的快感。尽管「PUNI 1000 - 柔软款」实属良品，但对于新入坑的杯友来说价格确实偏贵，因此一直不温不火没有话题，而就在我写本篇测评的时候「PUNI 1000 - 柔软款」也出现了断货情况，不知道是因为买的人太少，导致每次进货数量不多还是什么原因。但这款机体就各方面体验上绝对能让你值回票价，不虚此行。

【Spring】Spring Security 入门原理及实战
type: item
date: 2023-03-09T10:40:00+08:00
description: 1. 基础概述Spring Security 是 Spring 项目之中的一个安全模块，可以非常方便与spring项目无缝集成。在 Spring Boot 项目中 Spring Security 的集成也十分方便。本文主要介绍 Spring Security，以及其在 Web 应用中的使用。2. 快速入门2.1 创建项目现在我们创建一个基本的 SpringBoot 的 Web 应用项目，首先引入依赖：<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>然后创建启动类 SpringSecurityApplication：@SpringBootApplication public class SpringSecurityApplication { public static void main(String[] args) { SpringApplication.run(SpringSecurityApplication.class, args); } }然后在项目目录中新建包Controller用于表示控制层，在里面新建类AppController并编写代码:@RestController public class AppController { @RequestMapping("/hello") String home() { return "Hello,Spring Security!"; } }这时候我们启动项目，并访问http://localohost:8080/hello在页面中看到：Hello,Spring Security!2.2 加入依赖这个时候我们给 SpringBoot 项目添加 SpringScurity 依赖，在pom.xml的<dependencies>标签中添加如下依赖：<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>此时我们再一次访问http://localhost:8080/hello就会跳转到 Spring Security 的登录界面：说明 Spring Security 已经起作用了，但我们需要登陆才能继续访问。我们可以查看下这个页面的源代码，是这样： Please sign in Username Password Sign in 上面的div容器中包含了一个form，表单提交了三个数据：username【用户名】、 password【密码】、_csrf【CSRF安全防护相关】。Spring Security 默认的用户名是user，而默认密码则会在添加了 Spring Security 依赖后的项目启动时会随机生成。我们可以去控制台看下日志，会看到如下信息：在输入用户名和密码后成功登录，并能访问http://localhost:8080/hello的内容。2.2 自定义配置上面演示了默认情况下登录 Spring Security 的系统。如果我们想用自己的定义的账号密码，则需要改配置。我们新建包Config并在其中创建类MySecurityConfiguration，并添加如下代码：@Configuration @EnableWebSecurity public class MySecurityConfiguration extends WebSecurityConfigurerAdapter …