Open API 授权&鉴权机制设计

「万事开头难,视频号500粉直播需要你的助力!你的支持是我前进的动力!」

09c75d197b4d3b8c6121f6b181db6ecb.png

来源:juejin.cn/post/7299736066423930914

概述

基于 OAuth2 建设 Open API 平台授权机制,通过安全标准的方式授权给外部,保证部门应用数据的安全性。

OAuth2 定义了4种授权方式,但目前只需要供客户端在后台调用即可,所以仅考虑凭证式授权方式。

c9075479e99b0280d0ad9f59ee3265a0.png

设计方案

整体流程示意图:

caf0d398206aaf94ad6af7c04c68bce8.png

下面按照上面提到的四大模块来进行分析:

客户端

客户端通常是第三方服务,通过 Open API 获取资源。

8c3ad5da5bc0c97755cd936b556d89f5.png

客户端获取资源步骤:

第一步,用户需要在开放平台登录,然后注册客户端凭证,注册过程中给该凭证指定权限范围(Scope),注册完后会生成 client_id 和 client_secret,其中 client_secret 需要保密管理。

第二步,利用上一步拿到的 client_id 和 client_secret 发起请求获取令牌。

第三步,调用 API ,并在请求头上附带令牌。

令牌会过期,过期后重新请求获取令牌即可。

区分两种权限类型:

  1. API 权限,用户创建客户端凭证时指定(Scope)

  2. 数据权限,继承用户的数据权限

授权服务

授权服务负责授权和维护客户端凭证与权限的关系。

依赖 spring-security-oauth2-authorization-server 组件来构建该服务。

spring-security-oauth2-authorization-server 组件里面提供了基于 OAuth2 实现的授权服务,开箱即用.

库表介绍

  1. oauth2_registered_client:spring-security-oauth2-authorization-server 组件依赖的表,记录已注册了的客户端凭证。

  2. oauth2_authorization:spring-security-oauth2-authorization-server 组件依赖的表,记录已生成的令牌。

  3. oauth2_user_registered_client_relation:记录用户和客户端凭证的关系。

  4. oauth2_scope:权限范围(模块),支持两个层级。

  5. oauth2_open_api:记录对外API清单以及与 scope 的关系。

各个表的关系如下:

f2d21ca123ec658b4eb3849ba223c6df.png

授权

目前仅支持凭证式授权方式,不需要刷新令牌,令牌过期后重新获取即可。

spring-security-oauth2-authorization-server 组件内置了授权接口 /oauth/token。

JWT

令牌使用 JWT 生成,使用 JWT 的好处是:

  1. JWT 是一种自包含结构,可以存放一些关键信息,不需要额外查询。仅使用 JWT 令牌即可完成校验令牌有效性的动作。

  2. JWT 令牌由客户端来保管,且在里面存放客户端信息,服务器端不需要维护客户端状态,有利于服务端的无状态化和水平扩展。

  3. JWT 令牌通过签名来防止信息被篡改。

坏处是:

  1. 虽然信息不能被篡改,但是还是有泄漏的风险,建议对内容进行加密。

JWT 可以到 JWT.IOhttps://jwt.io/网站解析。

网关

网关是客户端访问的唯一入口,是外部请求连接内部服务的桥梁,授权,鉴权,路由都在这里完成。

网关处理两类请求,一类是授权(获取令牌)请求,一类是获取资源请求。

授权(获取令牌)请求

这类请求逻辑比较简单,网关接收到后直接路由到授权服务。

79c343e4f39783a4c22fabcf90fc5118.png

获取资源请求

此类请求需要网关先到授权服务获取到权限信息,鉴权通过后再路由到资源服务。

7681f15c8db85781bc1bc7eef8177d03.png

注意,网关对鉴权通过的请求在路由前会设置请求头 Open-Api-Client-IdOpen-Api-User-Id,作用有两个:

  1. 可以通过这两个请求头判断是否是 Open API 请求。

  2. 资源服务可以从这两个请求头获取到 client_id 和 user_id 信息。

资源服务

资源服务是实际的资源提供者。

请求来到资源服务代表鉴权已经通过,可以通过请求头 Open-Api-Client-Id 和 Open-Api-User-Id 来获取 Open API 调用者 client_id 和对应的 user_id 信息。

请求

获取令牌

请求接口:/oauth2/token

请求方式:POST

请求头:

请求参数:

名称类型描述
client_idstringclient_id
client_secretstringclient_secret
grant_typestring授权方式,目前仅支持 client_credentials

响应字段:

名称类型描述
access_tokenstring令牌
token_typestring令牌类型,目前仅支持 Bearer
expires_inint过期时间,单位秒,令牌过期后需要重新获取
scopestring权限范围

响应示例:

{
    "access_token": "eyJraWQiOiJyc2EtandrLWtpZCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI1MjMxODcwODQ5OTMxMjgwNTExIiwiYXVkIjoiNTIzMTg3MDg0OTkzMTI4MDUxMSIsIm5iZiI6MTY0NjAyODk1OSwic2NvcGUiOlsiMS0wIiwiMi0wIiwiMy0wIl0sImlzcyI6Imh0dHA6XC9cL3ZvZG1hcmtldHNzby55ZnhuLmxpemhpLmZtIiwiZXhwIjoxNjQ2MDMwMTU5LCJpYXQiOjE2NDYwMjg5NTksImNpZCI6IjUyMzE4NzA4NDk5MzEyODA1MTEifQ.Wn9APM9l64J761MJDs2nh61lITme575UyCXvyL0UftYEOebpoo60PSN3kLVGOXC5LIEztmzWF4ZcEOlkoHToU-9op3XML3e-HikmcpPOIExjDNdbimrY_zoHvzuX0LkTRxDNEwCrHkl7kHueJlwwXcaKM6jOLxyBD6wRL43DvaF4__hiI_RvMVh069SOgQlVRr0wpKtjegEfoXiMOhGYuRt_ArKBv8SWYjGL2Zz0dPA6Kxy8NowgVEHtwRRPSklSKPzq6sWsU9XMq1uGHBcf1EAMFD-CQAcFsL_b7oS4rGgOgT7kYDHRaMKGILnCEY4VZDA3FNTy1vnllumzN6quEA",
    "token_type": "Bearer",
    "expires_in": 1800,
    "scope": "1-0 2-0 3-0"
}

获取资源

获取资源请求需要包含 Authorization 请求头,示例:

Authorization = Bearer eyJraWQiOiJyc2EtandrLWtpZCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI1MjMxODcwODQ5OTMxMjgwNTExIiwiYXVkIjoiNTIzMTg3MDg0OTkzMTI4MDUxMSIsIm5iZiI6MTY0NjAyODk1OSwic2NvcGUiOlsiMS0wIiwiMi0wIiwiMy0wIl0sImlzcyI6Imh0dHA6XC9cL3ZvZG1hcmtldHNzby55ZnhuLmxpemhpLmZtIiwiZXhwIjoxNjQ2MDMwMTU5LCJpYXQiOjE2NDYwMjg5NTksImNpZCI6IjUyMzE4NzA4NDk5MzEyODA1MTEifQ.Wn9APM9l64J761MJDs2nh61lITme575UyCXvyL0UftYEOebpoo60PSN3kLVGOXC5LIEztmzWF4ZcEOlkoHToU-9op3XML3e-HikmcpPOIExjDNdbimrY_zoHvzuX0LkTRxDNEwCrHkl7kHueJlwwXcaKM6jOLxyBD6wRL43DvaF4__hiI_RvMVh069SOgQlVRr0wpKtjegEfoXiMOhGYuRt_ArKBv8SWYjGL2Zz0dPA6Kxy8NowgVEHtwRRPSklSKPzq6sWsU9XMq1uGHBcf1EAMFD-CQAcFsL_b7oS4rGgOgT7kYDHRaMKGILnCEY4VZDA3FNTy1vnllumzN6quEA

其中,

  • Bearer代表令牌类型,后面跟着访问令牌。

API 权限通配符配置示例

这里给一些 API 权限配置示例(只是建议)

URI请求方式描述API 权限通配符配置(对应 oauth2_open_api 表 path 字段)
/api/demo_entities/{id}GET根据id获取资源GET_/api/demo_entities/{id:\d+}
/api/demo_entitiesPOST新建资源POST_/api/demo_entities,POST_/api/demo_entities/
/api/demo_entitiesGET查询资源GET_/api/demo_entities,GET_/api/demo_entities/
/api/demo_entitiesPUT更新资源PUT_/api/demo_entities,PUT_/api/demo_entities/
/api/demo_entities/{id}DELETE根据id删除资源DELETE_/api/demo_entities/{id:\d+}

cc0c4a6c9768c0e3b3a905b465fc1004.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值