标题 | 基于OAuth2认证的RESTAPI设计与实践 |
范文 | 刘晓晖 秦子实 摘要:随着微服务技术架构与企业各业务单元中台的兴起,越来越多的系统会开放各种用途的REST API,对API调用者的身份认证成为保护数据安全的第一道防线。认证方法应具有易集成部署与API耦合度低等特性,以方便对现有API认证方式的改进。本文介绍基于OAuth 2.0标准的密码式令牌认证的设计与部署方法,可对REST API进行用户名密码式身份认证及权限鉴别,该方法具有代码量低易于部署等特点,适用于企业内部各应用系统的REST API认证。 关键词:OAuth 2.0;REST API;Python 中图分类号:TP393? ? ? 文献标识码:A 文章编号:1009-3044(2021)15-0056-02 1 概述 随着企业间业务系统及服务的联系越来越紧密,各系统和服务均开放了较多的API,供其他系统或用户进行调用。为了保护各系统的数据,需要对API调用者做出身份认证,并进行权限鉴别。普通的API第三方身份认证方式为第三方系统直接索取并提交用户的身份认证信息,API获得身份信息且确认后返回数据。该机制索取用户身份信息,首先存在信任问题和信息泄露风险;其次用户身份认证信息缺少失效机制,无法限制第三方获取数据的时效;此外,使用用户身份认证的权限通常即使用系统本身的权限管理机制,耦合程度较高,不利于开发、管理及后期扩展。 OAuth 2.0(以下简称OAuth2)是目前较流行的授权机制,通常用于向第三方应用提供用户数据或其他接口数据。OAuth2使用令牌(token)代替用户名密码进行身份认证与权限鉴别,因此用户信息泄露较低,并可以设置令牌时效,也可以直接在令牌中写入权限信息。 本文针对普通的API第三方认证方式中的不足,在企业内部网络中,使用OAuth2密码式令牌进行第三方应用系统的身份认证及权限鉴别。文中代码示例使用Python的FastAPI库进行演示。 2 OAuth2标准简介 2.1 OAuth 2.0标准 OAuth 2.0标准定义在RFC 6749文件中,引入令牌作为授权层,以隔离用户(资源所有者)与第三方(资源请求者)。即OAuth2的作用就是向第三方发放令牌。标准中定义了四种授权方式:授权码、隐藏式、密码式、客户端凭证。本文主要介绍在企业内部网络中各系统间API的认证及鉴权操作,因此仅介绍密码式OAuth2的应用。 2.2 密码式OAuth2原理 密码式OAuth2的认证过程为四种授权方式中较简单的一种。仅需要第三方向应用系统提供一次用户的用户名密码,确认后应用系统向第三方发放令牌,此后第三方均使用该令牌进行数据请求,具体过程如下: 假设用户在a.com中存放有数据,其中a.com/me用于查看用户个人信息,a.com/me/items用于查看用户拥有的所有条目。此时用户希望b.com获取其在a.com中的数据,则b.com主机向a.com/token发送POST令牌请求,表单附带用户的用户名密码及希望获得的权限。若a.com收到请求后通过身份认证及权限鉴别,则向b.com返回令牌(对称加密),令牌包含用户、权限及令牌时效。 此后,b.com向a.com请求数据时(如请求a.com/me),仅需要在请求头部附带Authorization字段,附带令牌数据即可。a.com将解析请求头部中的令牌,解密令牌确认身份及权限后,返回数据。 可以发现,整个过程除了在第一次请求中传递用户信息外,在令牌时效内的其他请求均仅通过令牌确认身份及权限。过程如下图所示: 3 密码式OAuth2应用 3.1 应用环境 本文使用Python的FastAPI构建REST API,均使用json封装数据。FastAPI支持密码式OAuth2,使用jwt加密token。 3.2 令牌发放接口设计 假设原系统目前具有两个REST API:a.com/me和a.com/me/items,为了支持OAuth2,需要添加a.com/token接口用于身份认证及令牌发放。本文为了方便演示,使所有API使用同一发布,发放令牌的token与原有的两个API应共享同一个SHA256密钥,用于加解密密钥。本文使用openssl生成一个32位的密钥,设置令牌时效时间15分钟。 a.com/token通过POST方式接收Form表单,按照密码式OAuth2标准规定,表单应包括四个字段:grant_type字段值固定为password;scope字段值为约定的权限码,权限码间用空格分隔;username字段为用户名;password字段为密码。 a.com/token返回一个使用jwt加密的json对象,access_token键的值即为令牌,这是一个加密的json对象,token_type值固定为bearer,其內容类似: 加密的内容解密后为{"sub": "johndoe", "scopes": ["me", "items"], "exp": 1593831859},通常约定sub键对应令牌主题,即用户名,scopes键对应权限列表,exp键对应时效时间戳。 3.3 现有API集成令牌认证设计 首先需要建立oauth2认证模板,包括指明认证方式为密码式、认证接口为a.com/token、权限包括“me”和“items”: 接下来需要编写一个认证函数,用于解析请求头部的Authorization字段,获得令牌并使用jwt进行解密,其函数签名如下: 现有的其他API需要集成密码式OAuth2认证时,只需要修改函数签名即可,例如检查用户账户是否可用的函数,只需在签名中增加认证函数和执行现有接口所需的权限: 当调用现有API get_current_active_user时,认证函数get_current_user的security_scopes参数即为了现有API索取的权限列表“["me"]”,token参数即为此次请求头部附带的认证令牌。使用jwt解析token后即可获得用户名和此次令牌包含的权限列表,使用用户名查询该用户所具有的权限,与令牌中包含的权限以及API索取的权限进行对比,即可明确此次请求是否被授权。 所需多个权限的API定义时,可直接在scopes列表中添加多个权限码,也可以进行链式认证,如下所示: a.com/me/items/接口需要“me”和“item”两个权限,可以复用a.com/me/的认证方法get_current_active_user先索取“me”权限,再使用本接口仅索取“items”权限即可。只要权限列表链中的一个权限未通过认证,接口就会返回访问未授权。 4 结束语 本文介绍了在企业内部场景中,使用OAuth2认证进行API第三方认证的设计方法。在对现有API添加OAuth2认证功能时,该方法具有安全性高、代码改动少的特点。此外OAuth2所用的对称加解密执行效率高,对现有系统的执行效率影响较小。因此,该方法是一种对现有系统影响较小的API第三方认证集成方法。 【通联编辑:梁书】 |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。