韩源-末日生存手册 - 系统
type: channel
link: https://kerryhan.cn/index.php/tag/系统/
items: 磁盘阵列技术
items: Linux常用命令
items: FastDFS分布式多机部署
items: 基于过滤拦截技术实现的身份认证方案
items: 【汇编语言】微机基本结构
items: 详解HTTP
items: 彻底搞懂Session、Cookie、token的区别
items: Shiro授权功能详解
items: shiro框架概念及原理
items: 单点登录原理及实现

磁盘阵列技术
type: item
date: 2023-11-08T03:28:22+00:00
description: 概述磁盘阵列（Redundant Arrays of Independent Drives，RAID），简单地说，就是讲若干块独立磁盘构成具有冗余能力的阵列。 他将很多块磁盘组合到一起构成一个磁盘组，来提升整个磁盘系统的读写性能及安全性。 利用同位检查（Parity Check）的观念，通过数据冗余实现磁盘系统中任何一个磁盘故障时整个磁盘系统仍然可以继续工作。 对于服务器开发和运维人员，RAID 是必须了解和使用的磁盘系统管理方式，随着时代的进步，越来越多的人在家庭、日常工作中使用简单的磁盘阵列来增加磁盘读写性能或提高数据安全性，甚至一些主板都已经提供了支持 RAID 的功能。 然而，RAID 概念很多，有时候会引起混淆，本文我们来详细介绍一下 RAID 技术的概念特征、基本原理、关键技术、各种等级和发展现状等方面的内容。RAIDRAID 是 1988 年美国加州大学伯克利分校的 D. A. Patterson 教授等首次在论文中提出的，起初，RAID 指的是廉价磁盘阵列，主要目的是为了节省购置大容量磁盘的成本，此后，RAID 咨询委员会将 Inexpensive 替换为 Independent 就是我们今日的 RAID，但其实质内容并没有改变。 RAID 主要利用数据条带、镜像和数据校验技术来获取高性能、可靠性、容错能力和扩展性，根据运用或组合运用这三种技术的策略和架构，拥有 RAID0 ~ RAID6 等的等级，近年来，存储厂商不断推出诸如 RAID7 、 RAID10/01 、 RAID50 、 RAID53 、 RAID100 等 RAID 等级，但这些并无统一的标准。 目前业界公认的标准是 RAID0 ~ RAID5 ，除 RAID2 外的四个等级被定为工业标准，而在实际应用领域中使用最多的 RAID 等级是 RAID0 、 RAID1 、 RAID3 、 RAID5 、 RAID6 和 RAID10。 从实现角度看， RAID 主要分为软 RAID、硬 RAID 以及软硬混合 RAID 三种。软 RAID 所有功能均有操作系统和 CPU 来完成，没有独立的 RAID 控制 / 处理芯片和 I/O 处理芯片，效率自然最低。硬 RAID 配备了专门的 RAID 控制 / 处理芯片和 I/O 处理芯片以及阵列缓冲，不占用 CPU 资源，但成本很高。软硬混合 RAID 具备 RAID 控制 / 处理芯片，但缺乏 I/O 处理芯片，需要 CPU 和驱动程序来完成，性能和成本 在软 RAID 和硬 RAID 之间。 目前来看，广泛采用的是以硬 RAID 为主的方式来实现 RAID，但各操作系统也都在不同程度上支持某些级别的软 RAID。关键技术RAID 主要有三个关键技术： 1. 镜像（Mirroring） 2. 数据条带（Data Stripping） 3. 校验（Data Parity） 不同的 RAID 级别会采用上述一到多个技术来获得不同的数据可靠性、可用性或IO性能。镜像镜像技术指的是将数据复制到多个磁盘，这样，在实际的使用中，只要有一个磁盘没有发生故障，都不影响整个磁盘系统的工作。 同时，并发地在多个磁盘上读取也可以提高读取性能，但是，相对的，镜像技术的写性能相对较低，每次写入都必须确保多个磁盘写成功。数据条带将数据分片保存在多个不同的磁盘，多个数据分片共同组成一个完整数据副本。 这与镜像的多个副本是不同的，它通常用于性能考虑。 数据条带具有更高的并发粒度，当访问数据时，可以同时对位于不同磁盘上数据进行读写操作， 从而获得非常可观的 I/O 性能提升。数据校验利用冗余数据进行数据错误检测和修复的技术。 冗余数据通常采用海明码、异或操作等算法来计算获得。 利用校验功能，可以很大程度上提高磁盘阵列的可靠性、鲁棒性和容错能力。 比起镜像 50% 的冗余开销 ，数据校验要小很多，它利用校验冗余信息对数据进行校验和纠错。 不过，数据校验需要从多处读取数据并进行计算和对比，会影响系统性能。优势大容量、高性能、可靠性、可管理性JBODJBOD 即 Just a Bunch Of Disks，他并不是标准的 RAID 等级。 它通常用来表示一个没有控制软件提供协调控制的磁盘集合，将多个物理磁盘串联起来，提供一个巨大的逻辑磁盘。 JBOD 的存放机制是由第一块磁盘开始按顺序往后存储，当前磁盘存储空间用完后，再依次往后面的磁盘存储数据。 它的存储性能完全等同于单块磁盘，而且也不提供数据安全保护，只是简单提供一种扩展存储空间的机制， JBOD 可用存储容量等于所有成员磁盘的存储空间之和。RAID0RAID 是一种简单、无数据冗余的数据带化技术，实际上它并不算是一种真正的 RAID，因为他不提供任何形式的冗余策略。 RAID0 将所在磁盘…

Linux常用命令
type: item
date: 2023-11-08T02:20:00+00:00
description: 功能描述代码删除文件夹find 文件夹名 -delete删除文件夹rm -rf 文件夹名删除文件rn -r 文件名退出文件编辑按ESC，然后：输入wq或者q查找a开头的文件ls a*删除所有a开头的文件rm -rf a*创建文件touch 文件名查看防火墙状态systemctl status firewalld/iptables开启防火墙systemctl start firewalld/iptables关闭防火墙systemctl stop firewalld/iptables删除当前目录下所有文件rm *上传文件scp test.png root@192.168.1.1:/home/查看端口监听状态netstat -aptu查看系统版本信息cat /etc/os-release文件重命名mv old_filename new_filename

FastDFS分布式多机部署
type: item
date: 2023-11-08T02:15:58+00:00
description: 情况描述用一台电脑做tracker负载均衡服务器，用两台电脑做storage做存储节点，两个storage归属于同group，数据自动进行备份。端口占用tracker占用端口为22122storage占用端口为23000storage的nginx映射为8888一个包既可以是tracker，也可以是storage，同时放出4个端口，8080，8888，22122，23000docker安装查看可用镜像docker search fastdfs拉取镜像docker pull delron/fastdfs在负载均衡服务器上，创建tracker服务docker run -d --name tracker --network=host -v /mydata/fastdfs/tracker:/var/fdfs delron/fastdfs trackernetwork=host意思是docker容器直接采用本机网络-v 后面是进行磁盘映射，将本机的电脑内存和docker容器内的内存映射到一起/mydata/fastdfs/tracker 为宿主机的物理内存地址，要实际存在在存储节点服务器上，创建storage服务docker run -d --name storage --network=host -e TRACKER_SERVER=192.168.32.128:22122 -v /mydata/fastdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage/mydata/fastdfs/storage 为宿主机的物理内存地址，要实际存在更改storage的nginx监听端口（可选）本操作均在storage服务器内执行进/etc/fdfs/目录下，编辑storage.conf，在最后一行，更改http端口号进/ust/local/nginx/conf ，编辑nginx.conf，将listen的监听端口也同样进行修改原生上传文件功能先将文件上传到宿主机与storage容器映射的文件夹内docker exec命令进入storage容器再storage容器下，找到该映射路径，进入该目录。输入命令/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 文件名 系统返回group名和路径名即成功通过http://storage容器IP地址:8888/系统上传后返回的信息。即可查看文件样例请求链接http://192.168.32.128:8888/group1/M00/00/00/wKgggGSD2feAXsv4AER92Sd_dzk072.jpg

基于过滤拦截技术实现的身份认证方案
type: item
date: 2022-03-20T04:58:00+00:00
description: 基于过滤拦截技术实现的身份认证方案系统基本流程用户发送请求过滤器过滤掉，访问需要保持登录状态的资源但是又没有携带token的请求拦截器拦截掉，访问需要具备相应权限的资源但是又没有对应权限的请求进入业务逻辑代码层级configMyFilterConfig：自定义过滤器的基础配置，对所有资源都进行过滤MyInterceptorConfig：自定义拦截器的基础配置，设置所需拦截的放行的URLcontrollerUserController：接口层entityUser：用户的实体对象。目前为了简化操作，不必新建权限表，所以在用户的实体对象里存放了list<String>集合，即用户的属性里就带着用户的所有权限信息filter：MyFilter：自定义过滤器，这块主要是判断用户请求有没有携带token，如果没有携带token，而且还访问的是需要携带token(即保持登录)的接口，那么就过滤掉用户的这次请求。但是，有的资源是属于开放资源，即不需要用户保持登录状态，因此，在这个模块，做了白名单列表，过滤器不对白名单列表进行过滤。interceptorMyInterceptor：自定义拦截器，这块主要是拦截需要权限的接口，获取用户的token，并且解析出用户权限信息，拿用户权限信息和接口所需权限进行比对，失败则拒绝，成功则让请求进行接口层。serviceUserService：接口所对应的具体业务逻辑，这块目前主要是有判断用户名密码，进而生成token，返回前端。utilJWTUtil：JWT工具类，可以用于生成JWT，解密JWT

【汇编语言】微机基本结构
type: item
date: 2021-09-15T12:54:00+00:00
description: 微机基本结构基本构成一般计算机包括五大部件，运算器、控制器、存储器、输入设备、输出设备。通过将运算器和控制器两大部件集成在一个集成电路芯片上，称为中央处理器，简称CPU，也叫微处理器。总线结构数据总线：CPU与内存或其他器件之间进行数据传送的通道地址总线：通过地址总线来指定存储单元控制总线：CPU通过控制总线对外部期间进行控制指令执行串行方式特点1：当CPU在指令执行阶段，不需要占用系统总线，但此时总线也不工作，因此系统总线的空闲时间比较多。 特点2：从存储器取指令、取数据或存数据时，总线处于忙状态，其所占用的时间也较长。而CPU却只需要花很短的时间去处理，因此大部分时间处于闲置状态。 指令流水线方式采用指令流水线可以显著提高工作效率。CPU内部采用了一种先进的指令六十线结构，这种结构可以有效而充分的利用各主要硬件资源。要实现指令流水线方式，从CPU组成结构上要划分成多个单元。 EUEU的主要任务是分析与执行指令，其具体包括1、从指令队列中取出指令代码，由控制器译码后产生相应的控制信号，继而控制各部件完成指令规定的操作。2、对操作数执行各种指定的算数或逻辑运算。3、向总线接口单元BIU发送访问主存或I/O的命令，并提供响应的地址和传送的数据。ALU取指令、存取数据

详解HTTP
type: item
date: 2021-07-12T12:29:00+00:00
description: 详解HTTPWeb及网络基础为了更好的理解什么是HTTP协议，我们需要先了解TCP/IP协议族。目前通常使用的网络都是在基于TCP/IP协议族的情况下进行信息传输，而HTTP也实际上是属于TCP/IP协议模型。要知道，不同的计算机之间要通过网络进行通信，那么必须遵循统一的规定，才能进行交流。这也就是协议的作用，通过制定规约，让不同的计算机可以进行信息互换。TCP/IP协议最重要的一点是对于信息加工传输进行了分层处理，这种分层结构清晰明了。TCP/IP协议族按层次划分为应用层、网络层、传输层、数据链路层。发送端数据依次经过应用层、网络层、传输层、数据链路层；接收端依次从数据链路层、传输层、网络层、应用层接收数据。而我们的HTTP协议就应用在应用层。HTTP报文用于HTTP协议交互的信息被称为是HTTP报文。客户端的HTTP报文叫做请求报文，响应端的HTTP报文称为响应报文。HTTP的报文是由多行数据构成的字符串文本。其结构大致可以分为报文首部和报文主体两块，两者通过空行进行划分，通常，报文是没有主体的。HTTP结构HTTP请求报文分为报文首部、空行、报文主体，其中报文首部内存放了请求行、请求首部字段、通用首部字段、实体首部字段和其他。HTTP响应报文分为报文首部、空行、报文主体，其中报文首部分为状态行、响应首部字段、通用首部字段、实体首部字段以及其他。HTTP状态码1XX：通知1XX系列响应代码仅在与HTTP服务器沟通时使用。100("Continue") 重要程度：中等，但（写操作时）很少用。这是对HTTP LBYL（look-before-you-leap）请求的一个可能的响应。该响应代码表明：客户端应重新发送初始请求，并在请求中附上第一次请求时未提供的（可能很大或者包含敏感信息的）表示。客户端这次发送的请求不会被拒绝。对LBYL请求的另一个可能的响应是417("Expectation Failed")。请求报头：要做一个LBYL请求，客户端必须把Expect请求报头设为字符串"100-continue"。除此以外，客户端还需要设置其他一些报头，服务器将根据这些报头决定是响应100还是417。101("Switching Protocols") 重要程度：非常低。当客户端通过在请求里使用Upgrade报头，以通知服务器它想改用除HTTP协议之外的其他协议时，客户端将获得此响应代码。101响应代码表示“行，我现在改用另一个协议了”。通常HTTP客户端会在收到服务器发来的101响应后关闭与服务器的TCP连接。101响应代码意味着，该客户端不再是一个HTTP客户端，而将成为另一种客户端。尽管可以通过Upgrade报头从HTTP切换到HTTPS，或者从HTTP1.1切换到某个未来的版本，但实际使用Upgrade报头的情况比较少。Upgrade报头也可用于HTTP切换到一个完全不同的协议（如IRC）上，但那需要在Web服务器切换为一个IRC服务器的同时，Web客户端切换为一个IRC的客户端，因为服务器将立刻在同一个TCP连接上开始使用新的协议。请求报头：客户端把Upgrade报头设置为一组希望使用的协议。响应报头：如果服务器同意切换协议，它就返回一个Upgrade报头，说明它将切换到那个协议，并附上一个空白行。服务器不用关闭TCP链接，而是直接在该TCP连接上开始使用新的协议。2XX: 成功2XX系列响应代码表明操作成功了。200("OK") 重要程度：非常高。一般来说，这是客户端希望看到的响应代码。它表示服务器成功执行了客户端所请求的动作，并且在2XX系列里没有其他更适合的响应代码了。实体主体：对于GET请求，服务器应返回客户端所请求资源的一个表示。对于其他请求，服务器应返回当前所选资源的一个表示，或者刚刚执行的动作的一个描述。-201("Created")重要程度：高。当服务器依照客户端的请求创建了一个新资源时，发送此响应代码。响应报头：Location报头应包含指向新创建资源的规范URI。实体主体：应该给出新创建资源的描述与链接。若已经在Location报头里给出了新资源的URI，那么可以用新资源的一个表示作为实体主体。-202("Accepted")重要程度：中等。客户端的请求无法或将不被实时处理。请求稍后会被处理。请求看上去是合法的，但在实际处理它时有出现问题的可能。若一个请求触发了一个异步操作，或者一个需要现实世界参与的动作，或者一个需要很长时间才能完成且没必要让Web客户端一直等待的动作时，这个相应代码是一个合适的选择。响应报头：应该把未处理完的请求暴露为一个资源，以便客户端稍后查询其状态。Location报头可以包含指向该资源的URI。实体主体：若无法让客户端稍后查询请求的状态，那么至少应该提供一个关于何时能处理该请求…

彻底搞懂Session、Cookie、token的区别
type: item
date: 2021-04-20T08:53:06+00:00
description: 彻底搞懂Session、Cookie、token的区别今天纠正了最大的一个误区，session、cookie、token到底是些什么东西，是有什么作用，值得记录一下。前言HTTP协议是无状态的，什么是无状态呢，就是你的下一次请求和上一次请求是没有任何关系的，服务器也不知道是一个人请求了两遍接口，还是两个人分别请求了一次接口。这样的好处肯定是服务器不需要作额外的操作来分辨，降低了服务器负载，但是但是但是，如果要做一个系统，这个系统操作很多，第一步是用户登录，后续的操作都是基于用户登录的情况下进行的，那么服务器就没办法识别了。所以这种情况行不通，必须有其他解决办法来实现服务器分辨用户的能力。Session会话模式session字面意思就是会话，所谓会话就是要保持你和另一个人沟通的这种状态。服务器为了区分用户，会给用户一个session_id，这个session_id一般存在客户端（浏览器）的cookie中，每次请求的时候都把session_id传给后端，后端很具session_id从session里面进行寻找，找到了，就相当于知道用户了。服务器会把session存放在服务器上，但是如果在高并发的情况下，服务器的session会存很多信息，而且session一般都在内存里，很影响服务器性能，所以在高并发状况下，不建议使用session。另外，它也不支持分布式，因为分布式相当于分成多个后端，那这样的话，我的session只能保存在一个后端，用户访问其他节点接口时候，就会出现认证失败的情况。token模式token模式相比于session模式，会更容易支持高并发。用户一开始请求服务器进行登录认证，认证成功之后，服务器根据用户的id等不敏感信息生成一个加密后的字符串序列，也就是token，把token放在响应头里，返回给前端用户，以后每次的请求，用户都需要带着token。后端接收到token，进行解析，解析成功，就认为用户已经登录，而且也可以根据当时加密所加的那些字段，识别用户身份。cookiecookie一般称为cookies，类型为小型的文本文件，相当于一个浏览器的小型数据库，用于存储简单不敏感信息，内存很小，一般存放session_id。如果系统采用session会话模式，那么前端从cookie中取得session_id，再去访问服务器，这是正常流程。由于cookie内存非常小，所以后续浏览器衍生出了SessionStorage、localstorage等浏览器的小型数据库。SessionStorage里的数据关闭浏览器自动清除。

Shiro授权功能详解
type: item
date: 2021-04-10T06:57:00+00:00
description: 授权，也叫访问控制，即在应用中控制谁能访问哪些资源（如访问页面/编辑数据/页面操作等）。在授权中需了解的几个关键对象：主体（Subject）、资源（Resource）、权限（Permission）、角色（Role） 主体主体，即访问应用的用户，在Shiro中使用Subject代表该用户。用户只有授权后才允许访问相应的资源。资源在应用中用户可以访问的任何东西，比如访问JSP页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。权限安全策略中的原子授权单位，通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源，如：访问用户列表页面查看/新增/修改/删除用户数据（即很多时候都是CRUD（增查改删）式权限控制）打印文档等等。。。如上可以看出，权限代表了用户有没有操作某个资源的权利，即反映在某个资源上的操作允不允许，不反映谁去执行这个操作。所以后续还需要把权限赋予给用户，即定义哪个用户允许在某个资源上做什么操作（权限），Shiro不会去做这件事情，而是由实现人员提供。Shiro支持粗粒度权限（如用户模块的所有权限）和细粒度权限（操作某个用户的权限，即实例级别的），后续部分介绍。角色角色代表了操作集合，可以理解为权限的集合，一般情况下我们会赋予用户角色而不是权限，即这样用户可以拥有一组权限，赋予权限时比较方便。典型的如：项目经理、技术总监、CTO、开发工程师等都是角色，不同的角色拥有一组不同的权限。隐式角色：即直接通过角色来验证用户有没有操作权限，如在应用中CTO、技术总监、开发工程师可以使用打印机，假设某天不允许开发工程师使用打印机，此时需要从应用中删除相应代码；再如在应用中CTO、技术总监可以查看用户、查看权限；突然有一天不允许技术总监查看用户、查看权限了，需要在相关代码中把技术总监角色从判断逻辑中删除掉；即粒度是以角色为单位进行访问控制的，粒度较粗；如果进行修改可能造成多处代码修改。显示角色：在程序中通过权限控制谁能访问某个资源，角色聚合一组权限集合；这样假设哪个角色不能访问某个资源，只需要从角色代表的权限集合中移除即可；无须修改多处代码；即粒度是以资源/实例为单位的；粒度较细。请google搜索“RBAC”和“RBAC新解”分别了解“基于角色的访问控制”“基于资源的访问控制(Resource-Based Access Control)”。授权方式Shiro支持三种方式的授权：编程式：通过写if/else授权代码块完成：Subject subject = SecurityUtils.getSubject(); if(subject.hasRole(“admin”)) { //有权限 } else { //无权限 }注解式：通过在执行的Java方法上放置相应的注解完成：@RequiresRoles("admin") public void hello() { //有权限 } 没有权限将抛出相应的异常；JSP/GSP标签：在JSP/GSP页面通过相应的标签完成：<shiro:hasRole name="admin"> <!— 有权限 —></shiro:hasRole> 后续部分将详细介绍如何使用。 授权基于角色的访问控制（隐式角色）1、在ini配置文件配置用户拥有的角色（shiro-role.ini）[users] zhang=123,role1,role2 wang=123,role1规则即：“用户名=密码,角色1，角色2”，如果需要在应用中判断用户是否有相应角色，就需要在相应的Realm中返回角色信息，也就是说Shiro不负责维护用户-角色信息，需要应用提供，Shiro只是提供相应的接口方便验证，后续会介绍如何动态的获取用户角色。2、测试用例（com.github.zhangkaitao.shiro.chapter3.RoleTest）@Test public void testHasRole() { login("classpath:shiro-role.ini", "zhang", "123"); //判断拥有角色：role1 Assert.assertTrue(subject().hasRole("role1")); //判断拥有角色：role1 and role2 Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2"))); //判断拥有角色：role1 and role2 and !role3 boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3")); …

shiro框架概念及原理
type: item
date: 2021-04-05T00:12:00+00:00
description: 一 shiro的简介shiro是apache的一个开源框架，是一个权限管理的框架，实现 用户认证、用户授权。二 shiro的架构图authenticator:认证器，主体进行认证最终通过authenticator进行authorizer:授权器，主体进行授权最终通过authorizer进行sessionManager:web应用中一般是用web容器对session进行管理，shiro也提供了一套session管理方式SessionDao:通过SessionDao管理session数据，以下是SessionDao的方法public interface SessionDAO {/*如DefaultSessionManager在创建完session后会调用该方法； 如保存到关系数据库/文件系统/NoSQL数据库；即可以实现会话的持久化； 返回会话ID；主要此处返回的ID.equals(session.getId())； */ Serializable create(Session session); //根据会话ID获取会话 Session readSession(Serializable sessionId) throws UnknownSessionException; //更新会话；如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用 void update(Session session) throws UnknownSessionException; //删除会话；当会话过期/会话停止（如用户退出时）会调用 void delete(Session session); //获取当前所有活跃用户，如果用户量多此方法影响性能 Collection<Session> getActiveSessions();cache Manager：缓存管理器，主要对session和授权数据进行缓存，比如将授权数据通过cacheManager进行缓存管理，和ehcache整合对缓存数据进行管理。三个核心组件:Subject, SecurityManager 和 Realms.Subject:即"当前操作用户"。但是，在Shiro中，Subject这一概念并不仅仅指人，也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着"当前跟软件交互的东西"。但考虑到大多数目的和用途，你可以把它认为是Shiro的"用户"概念。Subject代表了当前用户的安全操作，SecurityManager则管理所有用户的安全操作。SecurityManager:它是Shiro框架的核心，典型的Facade模式，Shiro通过SecurityManager来管理内部组件实例，并通过它来提供安全管理的各种服务。Realm: Realm充当了Shiro与应用安全数据间的"桥梁"或者"连接器"。也就是说，当对用户执行认证(登录)和授权(访问控制)验证时，Shiro会从应用配置的Realm中查找用户及其权限信息。从这个意义上讲，Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节，并在需要时将相关数据提供给Shiro。当配置Shiro时，你必须至少指定一个Realm，用于认证和(或)授权。配置多个Realm是可以的，但是至少需要一个。Shiro内置了可以连接大量安全数据源(又名目录)的Realm，如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求，你还可以插入代表自定义数据源的自己的Realm实现。三 shiro提供的功能Authentication：用户认证（登录）Authorization：权限控制Session Management：会话管理Cryptography：数据加密Web Support：支持web的APICaching：缓存Concurrency：支持多线程应用程序Testing：测试的支持“Run As”：假设一个用户为另一个用户的身份“Remember Me”：在Session中保存用户身份

单点登录原理及实现
type: item
date: 2021-03-17T07:13:00+00:00
description: 一、单系统登录机制1、http无状态协议 web应用采用browser/server架构，http作为通信协议。http是无状态协议，浏览器的每一次请求，服务器会独立处理，不与之前或之后的请求产生关联，这个过程用下图说明，三次请求/响应对之间没有任何联系3c91a3bf-25d8-4b1f-8e4a-68535c51aaa8 但这也同时意味着，任何用户都能通过浏览器访问服务器资源，如果想保护服务器的某些资源，必须限制浏览器请求；要限制浏览器请求，必须鉴别浏览器请求，响应合法请求，忽略非法请求；要鉴别浏览器请求，必须清楚浏览器请求状态。既然http协议无状态，那就让服务器和浏览器共同维护一个状态吧！这就是会话机制2、会话机制 浏览器第一次请求服务器，服务器创建一个会话，并将会话的id作为响应的一部分发送给浏览器，浏览器存储会话id，并在后续第二次和第三次请求中带上会话id，服务器取得请求中的会话id就知道是不是同一个用户了，这个过程用下图说明，后续请求与第一次请求产生了关联8a9fb230-d506-4b19-b821-4001c68c4588 服务器在内存中保存会话对象，浏览器怎么保存会话id呢？你可能会想到两种方式请求参数cookie 将会话id作为每一个请求的参数，服务器接收请求自然能解析参数获得会话id，并借此判断是否来自同一会话，很明显，这种方式不靠谱。那就浏览器自己来维护这个会话id吧，每次发送http请求时浏览器自动发送会话id，cookie机制正好用来做这件事。cookie是浏览器用来存储少量数据的一种机制，数据以”key/value“形式存储，浏览器发送http请求时自动附带cookie信息 tomcat会话机制当然也实现了cookie，访问tomcat服务器时，浏览器中可以看到一个名为“JSESSIONID”的cookie，这就是tomcat会话机制维护的会话id，使用了cookie的请求响应过程如下图518293d9-64b2-459c-9d45-9f353c757d1f3、登录状态 有了会话机制，登录状态就好明白了，我们假设浏览器第一次请求服务器需要输入用户名与密码验证身份，服务器拿到用户名密码去数据库比对，正确的话说明当前持有这个会话的用户是合法用户，应该将这个会话标记为“已授权”或者“已登录”等等之类的状态，既然是会话的状态，自然要保存在会话对象中，tomcat在会话对象中设置登录状态如下用户再次访问时，tomcat在会话对象中查看登录状态HttpSession session = request.getSession();session.setAttribute("isLogin", true);HttpSession session = request.getSession();session.getAttribute("isLogin"); 实现了登录状态的浏览器请求服务器模型如下图描述 每次请求受保护资源时都会检查会话对象中的登录状态，只有 isLogin=true 的会话才能访问，登录机制因此而实现。二、多系统的复杂性 web系统早已从久远的单系统发展成为如今由多系统组成的应用群，面对如此众多的系统，用户难道要一个一个登录、然后一个一个注销吗？就像下图描述的这样6dfbb0b1-46c0-4945-a3bf-5f060fa80710 web系统由单系统发展成多系统组成的应用群，复杂性应该由系统内部承担，而不是用户。无论web系统内部多么复杂，对用户而言，都是一个统一的整体，也就是说，用户访问web系统的整个应用群与访问单个系统一样，登录/注销只要一次就够了9fe14ab3-4254-447b-b850-0436e628c254 虽然单系统的登录解决方案很完美，但对于多系统应用群已经不再适用了，为什么呢？ 单系统登录解决方案的核心是cookie，cookie携带会话id在浏览器与服务器之间维护会话状态。但cookie是有限制的，这个限制就是cookie的域（通常对应网站的域名），浏览器发送http请求时会自动携带与该域匹配的cookie，而不是所有cookie4d58ccfa-0114-486d-bec2-c28f2f9eb513 既然这样，为什么不将web应用群中所有子系统的域名统一在一个顶级域名下，例如“*.baidu.com”，然后将它们的cookie域设置为“baidu.com”，这种做法理论上是可以的，甚至早期很多多系统登录就采用这种同域名共享cookie的方式。 然而，可行并不代表好，共享cookie的方式存在众多局限。首先，应用群域名得统一；其次，应用群各系统使用的技术（至少是web服务器）要相同，不然cookie的key值（tomcat为JSESSIONID）不同，无法维持会话…