Microservices Deployment via Docker/K8S
微服务是可以快速构建、修改和部署到独立生产环境中的小型代码单元。可以快速进行迭代开发和交付,从而部署应该也具有如下特征:
- 自动的——部署应该是能全部自动化的。
- 可重复的——部署流程是可以重复的,不因开发人员或环境变化而影响
- 完整的——部署成果应该是一个完整的虚拟机或者容器镜像(Docker),能够自包含运行
- 不可变的——服务镜像一旦构建运行时配置不应该被修改,修改应该从代码提交开始
云原生——Docker容器技术
容器是镜像的运行时实例。容器虚拟化操作系统资源,容器引擎划分操作系统资源(比如进程树,文件系统,网络栈等),将其打包到成为容器的虚拟操作系统中,运行一个应用。
容器技术不同于Hypervisor技术,后者将物理资源划分为虚拟机的虚拟版本,前者将操作系统本身划分为容器的虚拟版本。
容器镜像构建
Dockerfile是镜像构建的描述文件,以易于阅读的格式准确描述了应用及其依赖。Dockerfile由一系列指令组成,每条指令构建镜像的一层。镜像构建的基础目录就是Dockerfile所在的目录。
Dockerfile的构建指令包括:
- FROM:指定基础镜像
- RUN:在容器中执行命令
- COPY:复制文件到容器中
元数据指令包括:
- MAINTAINER:镜像作者
- LABEL:镜像标签
- EXPOSE:容器对外暴露的端口
- ENV:环境变量
- ENTRYPOINT:容器启动时执行的命令
- CMD:容器启动时执行的命令
- VOLUME:容器数据卷
Docker镜像的构建是分层叠加文件系统的过程,每条指令构建一层,镜像构建完成后,可以运行容器。文件是增量叠加的,删除上层镜像中的文件目录并不能真正的删除文件本身,而是在顶层layout中将文件隐藏,所以镜像文件并不能真正的变小。
- docker inspect命令可以查看镜像的构建过程,包括每一层构建的layer文件和指令。
- docker build命令可以逐行解析运行dockerfile构建镜像。
- docker history命令可以查看构建镜像的所有指令。
多段构建
多段构建有多个FROM命令,每一个FROM命令都会构建一个WORKINGDIR,以及一个独立的镜像,这为灵活运用镜像构建WORKSPACE提供了能力,甚至最终的运行时镜像可以引用完全不同的净化的base image,从而构建出与开发环境完全不同的运行时镜像。
同时也可以用 –target prod-client -f Dockerfile-final来灵活指定构建生产环境的客户端镜像。
容器网络栈虚拟化
Docker网络是基于容器网络模型的开源可插拔架构。libnetwork是CNM的实现,提供了docker的核心网络能力。Linux OS层面提供网络虚拟化的基础是VLAN,这是对eth0的拆分,每个VLAN都是一个独立的虚拟网络绑定到eth0.100等等,每个VLAN的流量都是隔离的,这是因为网桥间的隔离。Docker网络虚拟化基于VLAN,但是VLAN的隔离粒度是二层,而Docker网络虚拟化可以支持三层隔离,即每个容器可以拥有独立的IP地址,从而实现容器之间的子网隔离,也就是说在VLAN内部,即使可以将容器放在不同的子网段,保证网络间的相互通信。
VLAN
对于操作系统能L2的链路设计,是基于802.11Q扩展协议,让网卡从硬件上支持虚拟化,从而实现VLAN的隔离。VLAN不直连,并不代表两边的容器不同相互通信,如果VLAN是连向公网的,就可以通过公网通信。
VNET
虚拟子网一般是一个私网,类似于一个k8s cluster的所有容器都会在同一个VNET中,对于集群向外的通信,不要一个网关(也就是路由器)同时拥有私网IP(一般是网关IP)和公网IP(普通IP)从而可以建立路由规则,将私网向外访问的流量转发到网关,转发出去。类似于cluster的Egress IP。Ingress则是负载均衡的入口,对于外网的客户端,需要访问clkuster内部的应用,必须通过Ingress负载均衡反向代理流量进入容器,从而达到通信的目的,客户端只能发现到Ingress的IP。
容器运行时
runc是开放容器计划OCI运行时规范的实现。它的任务是与底层OS交互,启动和停止容器,docker每个容器都是runc创建的。OCI包括镜像规范,运行时规范,分发规范。
containerd管理容器的生命周期,包括拉取镜像和管理runc实例。
dockerd执行更高级别的任务,如暴露docker API,管理镜像,管理卷,管理网络等。
flowchart TD; A[runc内核级工作] --> B[containerd容器生命周期管理] B --> C[Docker守护进程CLI/API/Image/Network/Storage]
云原生——K8S容器编排技术
无服务器架构——基于容器的自动化构建和部署管道
2025工作项目计划
2024工作项目计划
2025年度个人规划
2025 个人小目标
- 个人工作生活
- Q1每个月安排一天个人时间,学习Optimus核心知识
- 思考下一个COD方向和领域:产品架构,产品经理,后端与运维
- Q1健康作息,不熬夜到12点后,保证基础睡眠
- Q2运动开始计划,通过合理安排作息,每周半小时起养成习惯,并逐步增加
- Q1每周一次睡前花十分钟番茄钟,复盘当周工作、中长期目标调整,减少纠结与内耗,看书增值
- 家庭生活
- 大宝的小学一年级思考和执行
- 拼音熟练度练习,朗读训练每日15分钟
- 汉字识字培训
- 控笔训练
- 日常数学加减训练
- 钢琴读谱,指法练习,肌肉重复训练,流畅背诵弹奏为目标
- 复习、预习课程习惯
- 演讲训练,植物节演讲、升旗手演讲、爸爸讲堂介绍
- 握笔姿势,写字姿势训练
- 数学拔高训练
- 语文阅读训练
- 小宝幼儿园前期准备
- 4、5月择校,9月正常入学
- 语言发展关注,发音纠正
- 自主如厕练习
- 自主吃饭习惯培养
- 自主穿脱衣服袜子入睡练习
- 认识数字大小数数
- 认字
- 安全意识训练
- 大宝的小学一年级思考和执行
- 职场价值、时间效率提升
- 快速阅读《高效能人士/家庭的七个习惯》,自我效能提升
- 快速阅读《卡耐基人性的弱点》,学会提升别人的效能
- 精读并且实践《How to Lead》,学会面对人工作
- 精读《这就是人性》,学会人性的特点,管理必须基于人性
- 个人充电:阅读书籍10本
- 职场、人性相关书籍, 有助平衡心态和目标:
- 学习领域预判思考方式,快速决策得出可执行尽量正确的选择
- 学习高效的项目管理方式,对于种类繁多的细碎项目如何高效的管理,并且针对不同的人建立不通的项目profile,合理安排资源
- 对于资深执行者的管理方式
- 对于资浅有潜力执行者的管理和引导方式
- 对于资浅Vendor的管理方式
- 合理授权,对于不同的选择,可以借由别人去实践通过验证
- 学习衍生品定价规则,交易系统,风险合规服务
- 管理风格建立,最大化生产力同时建立稳定良好的领导风格,项目进度把控
- 项目远期规划
- 项目落实原则把控
- 重组思维学习,在基本面了解情况下破局,精读《重组与突破》
- 领域相关背景书籍:
- 阅读CM bitemporal DB设计学习
- 阅读CM Risk Calc Engine设计学习
- 阅读CM Risk Storage & Pivot设计学习
- 阅读CM Entitlements Model设计学习
- 阅读Kindle《债券投资策略》,了解债券市场基本知识
- 阅读Kindle《债券组合投资》
- 阅读Kindle《投资组合绩效测评实用方法》
- 阅读《国富论》,了解经典生产理论以及劳动者与雇佣者的基本关系
- 阅读《利率互换通关秘籍》,了解利率基本概念
- 育儿和教育书籍:
- 父母效能训练
- 技术相关书籍:
- Kubernetes权威指南: 学习K8S部署技术
- 阅读《Helm学习指南》了解linux package管理发布基本知识
- 沟通技巧学习
- 非暴力沟通
- 别说你懂交际学
- 情绪控制学习
- 职场、人性相关书籍, 有助平衡心态和目标:
个人感悟
<< How to lead >>
领导力的基础
专注在人
当我们想要营销我的思想时,往往关注:
- 提供的功能
- 带来的好处
- 希望和美好愿景
但是影响他人的核心原则是,被影响人的需求(恐惧,贪婪,个性,空闲),帮助对方客服所有的困难,就容易影响别人。
传统销售手段
- 在问题上达成一致
- 题出解决方案
- 结束
激励人的原驱动力往往来自恐惧、贪婪和懒惰。
利用恐惧:一种是利用人对惩罚的恐惧,用于规范行为;另一种是消除恐惧,使得事情
进展顺利。利用贪婪:金钱和同事的认可度。
利用懒惰:对于对方本体是有益于她的本性,比如可以让他有利可图或生活变得容易吧。
向上管理
有潜力的领导者
- 适应性
- 自信
- 主动性
- 可靠性
- 野心
如何有效地向上管理
- 找到合适的老板
- 交付正确的项目
- 合适的反馈行为
保持正能量
让自己每天的生活积极正向
- 关注自己善长的
- 管理好自己的情绪
- 具象化自己想要做的事情
- 做有意义的事情
- 行动起来
做一个正能量的领导
- 开会中表达解决方案和机遇,而不是问题
- 寻找方案中的闪光点
- 主动寻找合适的项目
- 允许适当的冒险
不要做:
- 不抱怨工作
- 不嚼舌根
- 不推脱责任
做一个幸运的领导
领导需要持续为自己创造幸运,主要通过以下三个特性:
- 实践Practice:领导力是需要通过实践总结出的,深耕在一个领域或者一种类型的职能,而不是将注意力放在获取名利上。
- 坚持不懈Persistence:勤奋努力是成功的必要条件,对待失败,好的领导不会放弃、感到失望,而是感谢自己又少了一次失败的原因,因为它不会发生两次。
- 洞察力Perspective:幸运的人是在对的时间和对的地点等待幸运的发生,这样的洞察力是机遇对自己机构的了解,同时对对手的了解。对于成功模式的发现并不会太难,难的是对于其的坚持和持久的影响力让更多的人把一个观点实践成巨大的成功。
聪明的还是积极的
聪明人非常擅长看到事物的缺陷和风险,但是好的领导面对挑战具有如下特质:
- 冷漠的:冷漠的领导很难长时间维系一段很好的领导关系,好的领导需要避免冷漠对待挑战。
- 分析: 聪明人的分析能力可以快速找到问题存在的潜在风险,但是好的领导需要主要找到可能的解决方案让大家的思维活跃起来。
- 答案:聪明人总是想找到最优的答案,然而好的领导需要用经验和实验去解决实际的问题,而不是找到完美的答案。
- 行动力: 有行动才有机会赢,同事之间相处,请求原谅总是比请求帮忙容易,而人都是在错误中成长,所以不必因为害怕失败而踞足不前。
积极的解决问题
决策力是领导必须有的,只有决策后才能有行动力,让领导部署具体的实施方案。这往往比找到一个完美的解决方案更好。商业的世界总是在有限的时间和资源情况下,通过妥协解决尽量多的问题,而不是构造一个类似学院派的完美解决方案。
解决问题的步骤常常是:
- 找到问题
- 提出假设
- 提出数据结构
- 找到数据
- 分析数据
- 提出建议
启发式解决问题则是:
- 找到问题,以及问题的主人。确定问题是一个实质性的问题,找到问题产生的原因,而不是关注在为问题的表象和后果。
- 提出假设,找到可能的解决问题角度,咨询相关的人。
- 提出数据结构,迭代数据和定义,找到所有的可能性。
- 寻找数据,寻找尽量多的有效信息,快速缩小问题范围,避免扩大问题。
- 分析数据,讲问题,假设和解决方案完美的整合,不必是一个中立的表达。如果这不能解决需要的核心问题,必须重新提出假设。
- 在构造好的解决方案后,需要更多的资源参与,从而能够有效的扩大影响力。
对于解决问题的整体时间分配,20%的时间定义问题,50%的时间寻找数据证明自己的分析,和30%的时间推广和优化自己的解决方案。
除了关注每一个带解决的问题,也需要运用2/8原则搞清楚问题是属于2/8中的哪一侧:
对于公司的影响
对于问题主任的重要性
潜在解决方案的可行性
分析的难度
分析和解决方案的代价
复杂问题必须要进行拆解,并且运用2/8原则判定核心的问题方向。
寻找有效信息
- 市场的report是不是有偏向的,有没有幸存者偏见?
- 市场本质是博弈的,机械的分析只会有机械的决策,而不是纵观整个博弈后得到的最优解。
推荐方案需要保证数据的可靠性,如果有欠考虑的数据会令整个方案黯然失色。
心理学家提出保持正能量方法
- 关注在自己的优点上
- 管理好自己的情绪
- 可视化自己的成就
- 做一些自己喜欢的和工作无关的事情
- 善于行动,面向未来生活
保持专业性
- 学习领导力:从周围的优秀领导中学习这种能力,自我领悟
- 学习企业内部规则:
- 学习通用的专业能力
- 学习商业生存法则
实践领导力
掌握领导力
《这就是人性:认知觉醒的底层逻辑》
人性逻辑:别相信人,要相信人性
用利益去考验人性,你也许会输
- 趋利避害是人性,所以义才可贵
- 利是人类社会发展的动力,也是生存下去的根本。义是需要的,是人类社会得以稳固的基础,也是一个人处世的根本。这对矛盾从人出生开始就有,而能人往往能在矛盾中平和的生活。
- 不碰利益,人无坏人
- 弱者很多时候过度信奉世俗道德文化而忽视了学习人性,而强者很多时候都是人性高手,懂得用规则来治理人性。良好的规则设计,能够充分考虑人性的特点,去平衡人性弱点带来的弊端。
- 精明的利己主义者
- 势利本身只是一个中性词,生存是人类所有心理的出发点,会天然地依附掌握更多生存资源的人,并努力在最短时间内获得更多的利益。
- 人缘分为两种:资源性人缘,他们有值得别人“图谋”的地方。劳动性人缘:他们能够给人提供即时性的正面反馈上。
懂道德让你成为好人,懂人性让你成为富人
- 总和你谈感情的人,就是想少点付出
- 带不来价值的感情是廉价的。对方的考量主要还是从利益出发,理性的考虑帮助需要提供的价值是否符合他当下的立场。
- 真是话语权也不是靠分配而来的,而是自己挣来的——谁在价值协作中提供了更多不可替代的贡献,谁的真实话语权就更大。
- 即使想做好人,也要树立底线
- 你被好人标签绑架了吗?
- 道德约束是一种弱势文化,往往会将人羁羁绊在困境中,而强者文化则是客观的面对人性,利用人性,争取属于自己的机会。
金钱,可以检验人性
- 悟透赚钱的底层逻辑
- 文化属性决定层次和命运
* 思想狭窄
* 被错误或者过时的思想误导 - 满足人性的自私,才有才有可能赚到钱
- 人难免有自恋的情绪,会因为自己做了一些事情而陷入自我感动,但这没有用。
- 时不时审视自己的认知水平,有没有遵循底层规律办事。
- 文化属性决定层次和命运
- 你赚的每一份钱只会在认知空间内震荡
- 金钱只是一种媒介,是人用来换取商品和服务的中间态,而不是人的目标本身。人的目标是通过进去换取商品和服务,从而得到自己想要的情绪体验。
- 营造错觉,左右对方的价值判断
* 骗术本身往往不是为了以假乱真,而是通过真假虚实不断的试探,最终给受骗者一个错觉,改变了他原来的价值观。
认知觉醒:提升认知,看破生活假象
没有交换意识,哪有人脉关系
- 怕小人,不算无能
- 为自己的人生负责,不要过度依赖他人
- 如果你把自己的生命珠子交给别人,让别人替你保管,本质上来讲,是增加了对方的负担的。你的一切反应都无法阻止对方行使自己的权利。
- 圈子不同,不必硬融
打破思维禁锢,从内耗中找对出路
普通人要逆袭,首先得扒三层皮
- 扒掉俗事道德观
- 人生中的机会是要靠自己去抓住的,它不会凭空落到我们的头上。
- 扒掉规则的束缚
- 规则是人定的,尊重规则,理解规则、遵守规则、决不允许规则阻止自己朝更高的目标前进。
- 扒掉欲望的驱动
- 人最大的障碍其实是自己,只有真正成为自己的主人,看清事情背后的逻辑,才能从底层突围。
- 持志:发自内心地思考自己到底想做什么事,想成为怎样的人。
- 提升自己的认知:只有当你从更高更远的维度上才能看清事情背后的本质。
- 扒掉俗事道德观
想要获得通透,就要学会深度思考
- 无中心式的连续发散思维:发散思维是大多数人的思维方式,运用这类思维前需要先明确自己的目标,然后有方向的梳理思维成为有序状态。
- 反刍式思考:反思能够帮助增长事情对人的经验,但是过度的反刍式思考会阻碍事情的推进,让人抓不住机会。
- 浅层思考:浅层思考是感性直觉的思维,
- 动机挖掘:先搞清楚自己或别人的内在动机,看清本质的东西,避免不必要的弯路。
- 思考未来的终点:学会用未来的大脑,指挥活在当下的身体。
- 思考知识结构:三个层面理解知识:
- What:事情的表面,找到做的事情
- How:找到做这件事情的渠道,如何做
- Why:明白自己这样做的背后原理。
- 进行自我批判:不要认为自己什么都是对的,其实“自我”才是成功最大的障碍。遇到不如你的人,坚定自己的想法;遇到和你差不多的人,要怀疑自己的想法;遇到比你混的好的人,要否定自己的想法。
- 思考客观规律
要成事,从三个维度打破禁锢
- 学会包装自己
- 这个世界是靠实力说话的,很多时候,别人不能够直观地感受你地实力高低,所以你需要运用包装地手段向对方展示你地实力。
- 学会高调
- 面对利益要学会高调,敢于挣脱道德枷锁,敢于大胆追求自己地合法利益。
- 学会反击
- 人与人相处都有一个试探地过程,也就是对方要试探一下你的底线是什么。现实并不因为谁好说话,就为大家感激。
- 学会包装自己
野蛮生长:对己逆人性,对外顺人性
- 死不认错是人类共有的本性
- 境界高的人不会随便给人建议
- 每个人应该为自己的人生负责
- 别人寻求建议,不过是为自己已经做出的选择增加底气而已
- 不要妄图通过建议去拯救他人
- 过来人的话,其实是让人为难的经验
- 问基础的问题
- 对基本假设进行质疑
- 注意你的心理过程
- 总是反过来想
- 对证据进行评估
- 经常进行自我反思
成长的真相,都是逆人性的
- 心理内耗:为什么你活得这么累
- 为什么很多年轻人不愿意结婚了
- 怎样不被带节奏,保持独立思考
- 提升自己的知识储备和见识
- 有批判性思维,形成自己的思考
- 确立自我同一性
- 如何成为一个有影响力的人
- 通过各种方式不断重复要传达的信息
- 建立一整套思想体系
- 适可而止
顺从人性,轻松经营出好关系
面对过分地要求,不会拒绝怎么办
- 不拒绝:尝试拒绝一次,观察是否如假设中地情形一样失去对方。
- 代价很大时才会拒绝:举手之劳能满足对方,很难拒绝。
- 找借口拒绝对方:分清是你我谁的课题,合理借口回绝。
- 不带理由地拒绝:每个人为自己地需求负责。
- 通过开条件或提要求地方式拒绝:找出“是”地条件,反问对方能否接受。专业就是要拿来收钱的,不能随便给人。对于专业,认真做对不起我的专业,不认真做对不起你。
可以付出,但不要有付出感
- 有针对性地付出,不盲目
- 不夸大付出
- 刻意弱化自身能力地付出以体现牺牲地伟大
- 暗示对方不值得付出
如何提升自己地领导力思维?
人性亘古不变,学会野蛮生长
- 免费的东西人人喜欢,却无人珍惜
- 别人对你好是坏,取决于你
- 做人最怕心理想要利益,嘴上却讲道德
普通人逆袭的27条人性真相
- 直面人性的自私,学会从利益的角度审视一切
- 强者思维,人都会主动为强者找理由而不是弱者
- 利益绑定是最稳定的绑定,价值才是自己最宝贵的
- 职场里面的生存法则是有限资源残酷竞争
- 做事需要有慈悲心肠,也要有雷霆手段
- 我的价值决定于我是否被需要,这种价值是否具有稀缺性
- 扩展认值边界,利用信息差,搭建被动赚钱体系,利他才能从中获利
- 行走社会地生存法则是需要承认和接受自己地弱小,并且学会韬光养晦
- 强者对不可控地事情产生太多期望
- 规则是人制定地,看清背后地核心逻辑,才能合理突破规则,制定新的规则
- 解决问题也是解决本质的问题,而不是在复杂的题面上纠结原因
- 避免精神内耗的本质是课题分离,并且看清内耗的本质是什么,专注眼下的事情
Domain Driven Design Pattern Risk Calc
Authentication
Authentication服务鉴权机制
用户在访问系统或者服务时,服务器端需要验证用户是否拥有访问的权力,这个过程称为鉴权。在服务器-客户端架构的软件系统中,当一个没有经过鉴权的用户登录时,服务器可能会返回鉴权请求。鉴权是一种客户端和服务器协同认证的方式,有多种方式可以实现:
- HTTP Basic Authentication
- session-cookie
- Token 验证(JWT)
- OAuth(开放授权)
HTTP Basic Authentication
HTTP认证时一种无状态的认证模式,因此用户在提供相关凭据的请求中能够得到认证用户的访问,而服务器本身在接下来的请求中并不能持续保持登录状态。
HTTP基本认证的具体流程如下:
在你访问一个需要HTTP Basic Authentication的URL的时候,如果你没有提供用户名和密码,服务器就会返回401,返回Header中会包含类似”WWW-Authenticate: Basic realm=”test””信息。如果你直接在浏览器中打开,浏览器会弹出对话框提示你输入用户名和密码。
要在发送请求的时候添加HTTP Basic Authentication认证信息到请求中,有两种方法:
- 在请求头中添加Authorization信息:Authorization: “Basic {用户名:密码}的base64加密字符串”。
- 在url中添加用户名和密码。
其中,鉴权机制中的身份验证并非一定要依赖Basic方式的用户名密码作为凭据,可以通过如下方式:
“WWW-Authenticate: Negotiate” SPNEGO协议,支持Kerberos, NTLM点对点认证方式完成。在协商过程中:
- 可以请求 Authorization: Negotiate {kerberos票据}进行Kerberos验证
- 或者也能读取返回头中的 Authorization: Negotiate NTLMSSP{八字节质询码} ,并在请求头部中加入 Authorization: Negotiate NTLM{加密的质询码和明码用户名}
“WWW-Authenticate: Digest realm=”test”,qop=”auth”,nonce=”{md5加密时间},opaque=”{不透明字符串}”摘要认证协议,能避免明文传输数据。
- 在请求中需要加入 Authoriztion: Digest username=”guest”,realm=”test”,nonce=”{同上},qop=”auth”,nc=”00000001”,response=”{通过md5加密的user paswd httpmethod uri等信息}”,cnonce=”{客户端提供的非明文字符串}”,uri=”{uri信息}”
- 服务器需要检查时间在允许范围内,而且response匹配本地生成值。使用MD5算法的优势在于可以很快正向哈希,而无法短时间内逆向哈希得出用户密码等信息。
session-cookie鉴权
Session是HTTP协议中为了支持有状态的通信而发明的会话机制,本质上是通过服务器为用户建立sessionid从而保证用户的状态信息能够在服务器端保存。用户不需要反复进行登录认证就能保持会话。
而Cookie则是一种特殊的HTTP头部,能够在HTTP通信中保存一定的用户信息,如sessionid从而达到认证用户的目的。由于Cookie本身是针对某一域名而产生的,所以在发送Cookie过程中必须提供正确域名的sessionid才行。
具体流程如下:
Cookie鉴权常用Single Sign On场景,例如,于对于企业中的不同子域名的验证,可以通过结合SAML, CAS等协议完成。对于不同网络更加广泛的第三方验证则有OIDC协议支持。
Token 验证(JWT)
Token验证方式和Seesion验证方式很类似,不同的是Token本身包含一些有意义的信息:用户名、密码、过期时间等。Token本身由服务器签发,客户端请求的发送中需要包含 Authorization : JWT “{jwt token}”,服务器提取token信息通过相同的算法验证即可。相较于Session验证方式节约了分布式系统中服务器存储sessionid和用户信息的开销,只需要服务器拥有相同的密钥即可。
具体流程如下:
JWT(json-web-token)算法细节:
JWT由三部分”{header}.{payload}.{signature}’,两种算法生成,公式如下:
signature = sha256(base64(header)+’.’+base64(payload),{服务器密钥})
- header包含算法和类别信息,
- payload为加密部分,包含公有声明和私有声明,公有声明为约定的key,私有为公司定制key,
- signature,算法签名。
- sha256为header中写的加密算法,基于服务器密钥生成不同的加密签名,具有不可逆性
- base64为编码算法,可逆运算
OAuth2/OIDC认证
OIDC 即Open ID Connect, 是一种基于OAuth2授权流程,并且扩展了身份认证层的一种新的认证机制。
OIDC认证模型主要包含如下四个角色和一个令牌(完整术语参见http://openid.net/specs/openid-connect-core-1_0.html#Terminology):
- EU用户:End User:一个人类用户。
- RP客户端:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
- OP认证服务器:OpenID Provider,有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的ID Token身份认证信息和Access Token访问令牌;
- UE用户资源服务器:UserInfo Endpoint用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS。
- ID Token认证令牌:JWT格式的数据,包含EU身份认证的信息。通过OP提供。
认证流程如下:
其中,UserIndo EndPoint是一个受OAuth2保护的资源。在RP得到Access Token后可以请求此资源,然后获得一组EU相关的Claims,这些信息可以说是ID Token的扩展,比如如果你觉得ID Token中只需包含EU的唯一标识sub即可(避免ID Token过于庞大),然后通过此接口获取完整的EU的信息。此资源必须部署在TLS之上。
OIDC的支持的授权流程如下:
- Authorization Code(授权码模式):使用OAuth2的授权码来换取Id Token和Access Token。
- Implicit (简化模式):使用OAuth2的Implicit流程获取Id Token和Access Token。
- Hybrid(混合模式):混合Authorization Code +Implicit。
OAuth2授权模型
OAuth2的授权模型时为了已登录用户通过第三方应用访问资源服务器进行授权的流程,授权模型和OIDC相似,包含如下四个角色:
- 资源拥有者(User) - 指应用的用户,比如github的一个账户拥有者
- 认证服务器 (Authorization Server) - 提供登录认证接口的服务器,比如:github等
- 资源服务器 (Resources Server) - 提供资源接口及服务的服务器,通常和认证服务器是同 一个应用。
- 第三方客户端(Client) - 第三方应用,希望使用资源服务器提供的资源,比如你的一个支持通过github账户登录的应用
- 服务提供商(Provider): 认证服务和资源服务归属于一个机构,该机构就是服务提供商,比如github公司
OAuth2具有四种授权模式,下文将分述这四种模式具体流程:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
授权码模式(最为常见)
- 用户访问客户端应用
- 引导用户到认证服务器进行登录(此步骤需要携带客户端应用的clientId,可以是html直接转发认证服务器),用户输入用户名、密码
- 认证成功后,认证服务器向客户端应用发一个授权码code
- 客户端应用拿着授权码code,和clientId,clientSecret,去换取access_token
- 返回access_token给客户端应用
这种场景下,用户名、密码、客户端应用信息,都没有直接暴露在浏览器,是web下是最安全的。
简化模式
授权码模式的简化,用户认证成功后,直接将token返回给浏览器。因为某些应用没有前端服务器,只有一堆静态的html(很少见),这种模式,一般不用。
密码模式
适用场景:手机app ,这个客户端应用是你完全可以信任的,你的app就是自己公司开发的。但是这个模式并不适合在web场景下用,在web下,用户名密码并不是直接填给自己写的应用的,而是填在浏览器呈现的一个页面上的,这个浏览器是客户端应用的一个代理,浏览器是没法保证安全性的。
客户端证书模式
客户端应用直接发 clientId、clientSecret给认证服务器,发的令牌是针对客户端应用的,不是针对用户的。跟没授权一样,令牌不能识别用户身份。
Authentication实战
本章将着重描述如何在java springboot应用中实现相应的认证流程。springboot提供了一站式应用的开发模式,但是认证流程是需要spring security,同时具体的认证核心模块需要spring securty keberos或者spring security oauth组件支持。下文将主要介绍如何利用这两个模块实现具体的基于siteminder/spnego/oauth协议的认证流程。
siteminder sso + preauth
Siteminder是企业级认证产品,它提供了一站式认证中间件,从应用开发者的角度来看,就是采用了外部认证系统,应用不需要重新进行认证而是可以直接从siteminder处理过的http request header中提取SM_USER中拿到userprincipal()。因此从spring securty框架的角度之需要直接读取认证后的信息,而不需要再对request进行认证验证。这通常是一种企业内网用户认证采用的sso机制,因为用户之需要进行简单认证后就能得到对多种内部webapp的访问toekn,而且不需要进行细粒度的鉴权的场景适合大部分内部应用,但是,因为外部网站可容易会被假的header所欺骗,安全性较差而不会采用这种方式进行验证。
spnego auth
SPNEGO是微软设计的一种企业级认证协议,底层支持多种token协议,因此是应用proid常用的一种方式,因为应用的id会常常跑在不同的window/linux环境,而spnego能够支持多种密钥认证从而对跨系统认证能有很好的支持,这种认证方式需要用户自己执行认证检查,所以需要spring-security-keberos模块的相关auth provider进行验证。
oidc oauth2 + ping federate
oauth标准的实现一般是用oidc协议,spring security oauth2拥有对oauth2标准的鉴权模型的实现,并且可以通过适当的配置完成oidc用户验证。oauth单独并不能完成验证鉴权功能,需要部署一个oauth provider例如云服务商azure AD等,企业级内部可以自己部署ping federate服务器完成auth信息提供功能,并且向下兼容sso(即open Id)功能。
Ping Identity是支持OIDC和OAuth2标准的企业化产品
以https://abc.com作为签发域名,PingIdentity具体支持方式如下:
- openid配置查询Url:https://abc.com/.well-known/openid-configuration 返回json配置提供相关的认证终端信息,例如:
1 | { |
- authorization_code 授权码流程
- 用户发起请求到授权码endpoint:
打开chrome.exe,发起 GET https://abc.com/as/authorization.oauth2?client_id=foo&response_type=code&redirect=https%3A%2F%2Fabc.com%2Freal%2Fdocs%2F&scope=openid 请求
Chrome界面 redirect to url: https://abc.com/real/docs/?code=XXXXXXXXXXXXXXXXXX 获得授权码。
- 用户用返回授权码发起token请求:
1 | curl -k --data "grant_type=authorization_code" --data "client_id=foo" --data "code=xxxxxxx" --data "redirect_uri=https://abc.com/real/docs/" https://abc.com/as/token.oauth2 |
返回token json:
1 | { |
- 用户刷新过期token请求:
1 | curl -k --data "grant_type=refresh_token" --data "client_id=foo" --data "refresh_token=XXXXXXXXXX" --data "redirect_uri=https://abc.com/real/docs/" https://abc.com/as/token.oauth2 |
- JWT 验证流程:
对于RSA加密算法加密的token,需要公私钥才能进行加解密。 “jwks_uri”: “https://abc.com/pf/JWKS“, 认证服务器会用私钥将内容加密并且作为jwt的签名部分签发给客户端,资源服务器拿到jwt token后,需要用公钥解密签名,并且和明文的payload的进行比较确认没有篡改则为有效。整个算法过程有已有的实现例如jose4j。
对于对称加密算法的token,假设资源服务器和认证服务器都已经知道密钥内容,客户端拿到jwt token后,资源服务器需要利用密钥进行解密,并且验证payload的合法性即可。
Jetty Session Model
Domain Driven Design Pattern Bitemporality
Window Message
窗口消息
GUI应用程序必须响应来自用户和操作系统的事件。
来自用户的事件包括用户与程序交互的所有方式:鼠标点击、按键、触摸屏手势等等。
来自操作系统的事件包括程序之外的任何可能影响程序行为的东西。例如,用户可能插入一个新的硬件设备,或者Windows可能进入低功耗状态(睡眠或休眠)。
这些事件可以在程序运行时的任何时间发生,几乎可以按任何顺序发生。如何构造一个不能预先预测执行流(flow)的程序?
为了解决这个问题,Windows使用了消息传递模型。操作系统通过传递消息与应用程序窗口进行通信。消息只是指定特定事件的数字代码。例如,如果用户按下鼠标左键,窗口将接收到具有以下消息代码的消息。
C++
#define WM_LBUTTONDOWN 0x0201
一些消息具有与它们相关联的数据。例如,WM_LBUTTONDOWN消息包含鼠标光标的x坐标和y坐标。
要将消息传递给窗口,操作系统将调用为该窗口注册的窗口过程。(现在你知道窗口程序的作用了。)
https://learn.microsoft.com/zh-cn/windows/win32/learnwin32/your-first-windows-program
窗口句柄
窗口句柄是消息传递的源和目的,在每一个进程空间窗口句柄都是局部的,需要通过窗口名字去发现,对于某个窗口消息队列的监测,可以通过visual studio自带的spy++去定位监听并且调试。