【网络安全】OAuth 原理和安全实现

最近想了一下,现在 AI 生产内容的能力很强,如果我再生产哪些低质的笔记,那还不如不写,所以之后我发文章,都尽量用最简洁的语言把内容说明白,至少优于 AI,不然干脆别写了...

OAuth

理解 OAuth 之前,我们先看看 OAuth 是干嘛滴 ------

简单来说,OAuth 就是用于第三方身份认证的,一个例子就是:我上线了一个平台,平台想支持飞书账号登录,那么这时候就需要 OAuth 发挥作用了

角色

那么整个过程就有 4 个角色,

我的系统 ------ 飞书开放平台 ------ OIDC(OpenID Connect)身份提供商 ------ 用户

其中,OIDC(OpenID Connect)身份提供商充当翻译官的角色,通过连接器(Connector)对接飞书账号系统

流程

飞书 Dex(后端) 浏览器 飞书 Dex(后端) 浏览器 #mermaid-svg-uo2X7lbEvU0RYuca{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uo2X7lbEvU0RYuca .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uo2X7lbEvU0RYuca .error-icon{fill:#552222;}#mermaid-svg-uo2X7lbEvU0RYuca .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uo2X7lbEvU0RYuca .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uo2X7lbEvU0RYuca .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uo2X7lbEvU0RYuca .marker.cross{stroke:#333333;}#mermaid-svg-uo2X7lbEvU0RYuca svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uo2X7lbEvU0RYuca p{margin:0;}#mermaid-svg-uo2X7lbEvU0RYuca .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uo2X7lbEvU0RYuca text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-uo2X7lbEvU0RYuca .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-uo2X7lbEvU0RYuca .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-uo2X7lbEvU0RYuca .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-uo2X7lbEvU0RYuca .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-uo2X7lbEvU0RYuca #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-uo2X7lbEvU0RYuca .sequenceNumber{fill:white;}#mermaid-svg-uo2X7lbEvU0RYuca #sequencenumber{fill:#333;}#mermaid-svg-uo2X7lbEvU0RYuca #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-uo2X7lbEvU0RYuca .messageText{fill:#333;stroke:none;}#mermaid-svg-uo2X7lbEvU0RYuca .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uo2X7lbEvU0RYuca .labelText,#mermaid-svg-uo2X7lbEvU0RYuca .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-uo2X7lbEvU0RYuca .loopText,#mermaid-svg-uo2X7lbEvU0RYuca .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-uo2X7lbEvU0RYuca .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-uo2X7lbEvU0RYuca .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-uo2X7lbEvU0RYuca .noteText,#mermaid-svg-uo2X7lbEvU0RYuca .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-uo2X7lbEvU0RYuca .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uo2X7lbEvU0RYuca .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uo2X7lbEvU0RYuca .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uo2X7lbEvU0RYuca .actorPopupMenu{position:absolute;}#mermaid-svg-uo2X7lbEvU0RYuca .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-uo2X7lbEvU0RYuca .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uo2X7lbEvU0RYuca .actor-man circle,#mermaid-svg-uo2X7lbEvU0RYuca line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-uo2X7lbEvU0RYuca :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 回调中的 code 经浏览器传递,属于正常的前端通道 app_secret 只在后端换取 token 时使用 GET /auth1302 到 /dex/auth?client_id=myapplication&...2点击"飞书登录"3302 到 open.feishu.cn/authen?app_id=cli_xxx&redirect_uri=dex/callback&state=...4打开飞书授权页并输入密码5302 到 dex/callback?code=XXX&state=...6请求 /dex/callback?code=XXX&state=...7POST /oauth/token(app_id + app_secret)8返回 access_token9

授权码流程将登录拆成两个通道:

  • 浏览器 ------ 前端通道 ------ 授权服务器
  • 服务器 ------ 后端通道 ------ 授权服务器

其中:

  • 前端通道只传递一次性的、偷了也没用的东西,比如:client_id、state、code授权码、重定向的uri
  • 后端通道传递长期有效的秘密:app_secret

安全分析

通过上面的流程,我们也就发现了 OAuth 安全的关键就是:app_secret。

这个 app_secret 是我们的应用发送给飞书的证明我们是这个应用的凭据。

那么如果 app_secret 泄露就会出现:

  • 伪造身份调用飞书 API,能导出什么信息取决于飞书后台给当前应用开了什么权限
  • 直接换取 access_token ,不需要 Dex (OIDC(OpenID Connect)身份提供商 ) ------ 一个原本被保护的动作,现在谁都能做

扩展一下思路,针对任意的 secret 泄露问题,可以从以下几个角度考虑:

  1. 这个凭据是什么的凭据
  2. 这个凭据本来是干什么的
  3. 现在我可以用这个凭据干什么

安全的 OAuth 设计

  1. code 不能被随意劫持,只能送到登记过的应用 ( OAuth 服务器控制)
  2. code 必须得是自己申请的 ------ 设备码绑定
  3. code 必须是一次性的、绑定指定应用
  4. 只能使用不可修改的唯一编码识别是谁
  5. secret 存储必须安全
相关推荐
黄焖鸡能干四碗2 小时前
大数据平台安全防护策略方案(PPT)
大数据·运维·网络·安全·web安全·制造
林伽一2 小时前
端侧模型与运行框架双轮驱动,智能体工程化进入深水区|2026年10月16日
人工智能·科技·安全·ai·开源
Bruce_Liuxiaowei5 小时前
2026年10月第3周网络安全形势周报
安全·web安全·网络安全
是真的小外套15 小时前
第13章:网络安全漏洞防护原理与应用
安全·web安全·php
Ikalus198816 小时前
检查自己写着「这不会让任务失败」:一条 Critical 风险就这么过了 178 天
安全·架构
仿生joe会梦见漫天的大雪吗16 小时前
CTF Misc 工具选型指南:按题型分类的工具、原理与限制
后端·安全
QYR-分析17 小时前
工业安全无线遥控器:5.4% 稳步增长,起重与移动机械的安全控制终端
安全
研发小能19 小时前
金融行业 DevSecOps 解决方案:把安全内建到研发全流程
安全·金融·devops·嘉为蓝鲸
xjxijd19 小时前
AI 安全进入爆发周期:智能体安全成下一阶段核心竞争高地
人工智能·安全·ai