微服务认证与授权:01 — 概念

本文讲解阅读本系列其余内容之前你需要了解的核心安全概念。

术语表

  • IdP(身份提供方,Identity Provider) --- 签发身份与令牌。这里是 Keycloak
  • PEP(策略执行点,Policy Enforcement Point) --- 拦截请求、执行决策。这里是 Kong
  • PDP(策略决策点,Policy Decision Point) --- 依据策略判定允许/拒绝。这里是 OPA
  • 资源服务器(Resource server) --- 拥有受保护的数据,并会再次校验令牌。这里是 banking-api-service
  • JWT --- 携带身份与声明(claims)的签名令牌。

认证 vs 授权

认证回答的是:

  • 你是谁?

授权回答的是:

  • 你被允许做什么?

在本项目中:

  • Keycloak 负责认证。
  • KongOPA 负责执行授权。
  • banking-api-service 在返回银行数据前也会校验调用方。

IdP

IdP(身份提供方)是这样一个系统:

  • 存储用户
  • 校验用户名与密码
  • 登录成功后签发令牌

在本项目中,Keycloak 就是 IdP。当 alice 登录时,Keycloak 对她进行认证并签发一个 JWT。

JWT

JWT 是一个携带身份信息与声明(claims)的签名令牌,例如:

  • 用户名
  • 角色
  • 受众(audience)
  • 签发者(issuer)
  • 自定义声明,如 customer_idaccount_ids

重要:JWT 不会仅因为存在就被信任 ------ 接收方必须对它进行校验。

校验项包括:

  • 签名
  • 签发者(issuer)
  • 受众(audience)
  • 过期时间(expiry)

PEP

PEP(策略执行点)位于受保护资源之前,要么:

  • 放行请求,要么
  • 拦截请求。

在本项目中,Kong 是位于边缘的 PEP。来自 aliceops-admin 的每个请求,都要先经过 Kong 才能到达 banking-api-service

PDP

PDP(策略决策点)评估策略规则并返回一个决策:

  • 允许,或
  • 拒绝。

在本项目中,OPA 是 PDP。Kong 把请求细节发送给 OPA,OPA 评估策略并返回决策。这样就把授权逻辑同 Keycloak 中的认证、以及 banking-api-service 中的业务逻辑分离开来。一个简单的理解方式:Keycloak 证明用户是谁,Kong 拦截请求,OPA 回答该用户是否被允许执行该操作。

为什么要拆分 IdP、PEP 与 PDP

把这些角色分开,是因为它们解决的是不同的问题:

  • Keycloak 证明身份。
  • Kong 在网关处执行访问控制。
  • OPA 判定某个请求是否应被允许。
  • banking-api-service 运行业务逻辑并提供纵深防御。

这种分离让系统更易于理解、也更易于修改。

Spring Boot 微服务

本项目使用两个 Spring Boot 服务:

  • banking-api-service
  • identity-bootstrap-service

为什么用微服务:

  • banking-api-service 对外暴露受保护的银行 API。
  • identity-bootstrap-service 负责把演示用户初始化到 Keycloak
  • 每个服务都有单一、清晰的职责。

概念图

#mermaid-svg-Kir5WyBv2KbJtZYn{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-Kir5WyBv2KbJtZYn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Kir5WyBv2KbJtZYn .error-icon{fill:#552222;}#mermaid-svg-Kir5WyBv2KbJtZYn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Kir5WyBv2KbJtZYn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Kir5WyBv2KbJtZYn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Kir5WyBv2KbJtZYn .marker.cross{stroke:#333333;}#mermaid-svg-Kir5WyBv2KbJtZYn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Kir5WyBv2KbJtZYn p{margin:0;}#mermaid-svg-Kir5WyBv2KbJtZYn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster-label text{fill:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster-label span{color:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster-label span p{background-color:transparent;}#mermaid-svg-Kir5WyBv2KbJtZYn .label text,#mermaid-svg-Kir5WyBv2KbJtZYn span{fill:#333;color:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn .node rect,#mermaid-svg-Kir5WyBv2KbJtZYn .node circle,#mermaid-svg-Kir5WyBv2KbJtZYn .node ellipse,#mermaid-svg-Kir5WyBv2KbJtZYn .node polygon,#mermaid-svg-Kir5WyBv2KbJtZYn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Kir5WyBv2KbJtZYn .rough-node .label text,#mermaid-svg-Kir5WyBv2KbJtZYn .node .label text,#mermaid-svg-Kir5WyBv2KbJtZYn .image-shape .label,#mermaid-svg-Kir5WyBv2KbJtZYn .icon-shape .label{text-anchor:middle;}#mermaid-svg-Kir5WyBv2KbJtZYn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Kir5WyBv2KbJtZYn .rough-node .label,#mermaid-svg-Kir5WyBv2KbJtZYn .node .label,#mermaid-svg-Kir5WyBv2KbJtZYn .image-shape .label,#mermaid-svg-Kir5WyBv2KbJtZYn .icon-shape .label{text-align:center;}#mermaid-svg-Kir5WyBv2KbJtZYn .node.clickable{cursor:pointer;}#mermaid-svg-Kir5WyBv2KbJtZYn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Kir5WyBv2KbJtZYn .arrowheadPath{fill:#333333;}#mermaid-svg-Kir5WyBv2KbJtZYn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Kir5WyBv2KbJtZYn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Kir5WyBv2KbJtZYn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kir5WyBv2KbJtZYn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Kir5WyBv2KbJtZYn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kir5WyBv2KbJtZYn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster text{fill:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn .cluster span{color:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Kir5WyBv2KbJtZYn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Kir5WyBv2KbJtZYn rect.text{fill:none;stroke-width:0;}#mermaid-svg-Kir5WyBv2KbJtZYn .icon-shape,#mermaid-svg-Kir5WyBv2KbJtZYn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Kir5WyBv2KbJtZYn .icon-shape p,#mermaid-svg-Kir5WyBv2KbJtZYn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Kir5WyBv2KbJtZYn .icon-shape .label rect,#mermaid-svg-Kir5WyBv2KbJtZYn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kir5WyBv2KbJtZYn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Kir5WyBv2KbJtZYn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Kir5WyBv2KbJtZYn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} proves identity
allow or deny
business data
User
IdP: Keycloak
JWT
PEP: Kong
PDP: OPA
Spring Boot Service

最重要的是什么

如果你只记住一件事,就记住这个:

  1. Keycloak 说明用户是谁。
  2. Kong 拦截或转发请求。
  3. OPA 判定该操作是否被允许。
  4. banking-api-service 再次校验,并返回银行响应。

Next: 02 --- 本项目架构

相关推荐
KobeSacre1 小时前
DelayQueue 源码
java·开发语言
Wang's Blog1 小时前
JavaWeb快速入门: Filter与Listener核心详解
java·filter·listener
狂炫冰美式1 小时前
凌晨睡不着,我给台风巴威写了个追踪网站
前端·后端·github
zfoo-framework1 小时前
mongodb性能调优 1.从慢查询分析索引 2.掌握索引最左匹配原则!!!
java
烤代码的吐司君2 小时前
Redis IO 多路复用原理与引入原因深度解析
数据库·redis·php
AIGS0012 小时前
企业AI落地:从RAG到AgentRAG的技术跃迁
java·人工智能·人工智能ai大模型应用
雪隐2 小时前
用Flutter做背单词APP-01服务器?不存在的,我家里就有
前端·人工智能·后端
2601_962341302 小时前
计算机毕业设计之jsp考研在线复习平台
java·大数据·开发语言·hadoop·python·考研·课程设计