`
bugtags
  • 浏览: 29972 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

RESTful Api 身份认证中的安全性设计探讨

 
阅读更多

REST 是一种软件架构风格。RESTful Api 是基于 HTTP 协议的 Api,是无状态传输。它的核心是将所有的 Api 都理解为一个网络资源。将所有的客户端和服务器的状态转移(动作)封装到 HTTP 请求的 Method  之中.

而本篇文章则主要是讨论 RESTful Api 身份认证安全性设计.

没有绝对的安全,这个话题很深,下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正。

由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以只要和用户身份有关的请求都会带上身份认证信息。(很多时候客户端事先并不知道某个 api 后期会不会加入身份判断,所以我们一般都会选择每个请求都会带上认证信息,如果有的话。

Http Basic Authentication

Http Basic 是一种比较简单的身份认证方式。在 Http header 中添加键值对 Authorization:  Basic xxx (xxx 是 username:passowrd base64 值)。

例如 username 为 zmk ,password 为 123456,请求则如下

GET /auth/basic/ HTTP/1.1

Host: xxxxx

Authorization: Basic em1rOjEyMzQ1Ng==

而 Base64 的解码是非常方便的,如果不使用 Https ,相当于是帐号密码直接暴露在请求中。

危险性高,实际开发者使用的应该几乎为 0。

顺便提下 DIGEST 认证,和 BASIC 认证相差无几,而且不适合 api 设计,实际又需要两次请求,首次请求,服务器端返回 401,并且带上 nonce 值,然后客户端再利用 username+password+nonce 默认 MD5 之后再请求。对 http 请求的作用是仅仅防止二次请求,对身份认证并没有什么提升。

Access Token

不知道是否应该这么称呼。原理即当客户端登录完毕之后,给客户端返回一个 token,服务器端控制该 token 的有效期,每次请求都带上该值,然后服务器端做验证,退出之后,客户端通知服务端端销毁 token,客户端本地也销毁。但是如果抓包获取到 token,就能任意伪造请求了。

同时 api 接口还存在被第三方开发者或者公司随意利用的风险。也就是说,别人可以非常轻易的就弄出一个你们 app 的复制版,而且还用的你们的所有资源。

危险性高,实际开发估计使用得还不少。

Api Key + Security Key + Sign

下图是我们自己每次请求的身份认证的方式,如有不足,请大家指出。可以说是 JWT 的自定义版吧。


 

这里的认证逻辑即:

用户登录返回一个 api_key 和 security_key;

然后客户端将 security_key 存在客户端;

当要发送请求之前,通过 function2 加密方法,把如图所示的五个值一起加密,得到一个 sign;

发送请求的时候,则将除去 security_key 之外的值,以及 sign 一起发送给服务器端;

服务器端首先验证时间戳是否有效,比如是服务器时间戳 5 分钟之前的请求视为无效;

然后根据 api_key 得到 sercurity_key;

最后验证 sign。

Api key 的作用是什么?(补)

看到有朋友在头条问了这个问题,说下我的实际使用场景:

api key 是用来标识每个不同用户的(也就是说 api key 和用户 id 一一对应的),同时也用来验证security_key 和 sign 的。

比如有 2000 万用户,以 redis 作为数据库,将 api_key 为键,security_key 作为值,api_key 散列分布(比如对末尾位字符的 ASCII 对 20 取模)到 20 个 hashes 里。

当用户请求过来的时候首先根据 api_key 找到对应的 hashes,首先 HEXISTS 检查该 api_key 是否存在,存在则通过 HGET 取出该值,最后一起验证 sign。

是否需要加上时间戳验证?

上面的认证逻辑中加密得到签名的时候,把时间戳加进去是为了在一定程度上屏蔽了一些无效的请求,可以略去,也可以设计的更加严格。如果想防止恶意的 api ddos 攻击,这一步验证肯定是不行的。需要做更多的验证,比如用户验证,ip 验证等。可以参考 github 的 api 的设计。它会在返回的 http 头信息里带上

X-RateLimit-Limit: 5000

X-RateLimit-Remaining: 4999

表示这个接口在某一时间段内,该授权用户调用该接口的最大次数为 5000次,该时间段内还剩余 4999 次。当然,这样的验证加上之后,在代码的执行效率上肯定会有所影响。

是否需要将 request_parameters 也加入到 sign 生成的算法之中?

也不是必须的,仅仅是为了请求的真实性,减少请求的伪造,比如有人抓包拿到 http 请求之后,如果没有验证 sign 这步,那么别人就可以非常简单的修改请求的参数,而请求都会生效。

这里将 request_parameters 也加入到签名之中,就减少了伪造请求的可能性,但是无法杜绝,破坏者可能就非要黑你,又对逆向工程非常熟悉,找到我们加密算法的实现,依然可以未知出合法的签名,所以我们常说,服务器端永远不能相信客户端的请求都是安全的、合法的,需要做验证的都还是不能省略。

同时这(sign算法)也造成了 api 接口调试的成本,api 测试工具必须也得实现那一套算法,或者是设置在开发环境下不做验证。我们在配置开发环境的时候则是 vpn 连测试服务器所在内网,然后进行测试,否则开发环境也存在被人利用的风险。

项目实例 https://github.com/zhoumengkang/netty-restful-server

JWT

JWT (JSON Web Token) 使用流程如下(图片来自官网)


 

其认证机制也是登录,发放密钥给客户端,然后客户端每次发送请求的时候通过 JWT 的算法规则组装 JWT 的Auth Header,服务器端作验证。

web 授权认证的原理万变不离其宗,都是如此。

只不过 JWT 呢,自定了一套认证协议。格式为 Header.Payload.Signature。比如 xxxxx.yyyyy.zzzzz。签名内容是有 Header+Payload+Secret 通过 HMAC SHA256 算法加密而成。

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload),

secret)

而请求的很多参数键值对都可以放在 Payload 里面。完整讲解请求看官方的介绍 http://jwt.io/introduction/

需要注意的一点,依照 JWT 的协议,只有一个 secret,无法得知该用户是谁,所以在 secret 该值中必须要可以解码出用户的 id。

而我们自定义认证协议的时候 header 感觉就没有必要了,使用什么算法事先定义好即可。所以我们也没选择这种方式而是上面的那种方式。

其他

oauth2.0 则属于第三方认证,不在本篇的讨论范畴之内,可以阅读 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

来自:周梦康

链接: http://mengkang.net/620.html

 


 
分享到:
评论

相关推荐

    RESTFUL API设置最佳实

    本文将探讨 RESTful API 设计的最佳实践,帮助开发者构建高效、易用且灵活的 API。 #### 二、RESTful API 的关键要求 设计 RESTful API 时,应遵循以下关键要求: 1. **遵循 Web 标准**:在适当的地方使用 Web ...

    Python语言开发RESTful API指南

    身份验证(Authentication)和权限验证(Permission Validation)是确保API安全的重要环节。常用的认证机制有基本认证(Basic Auth)、摘要认证(Digest Auth)和OAuth。基本认证是通过用户名和密码进行认证,摘要...

    restful API

    本文旨在深入探讨RESTful API的核心设计理念及其应用实践。 #### 一、协议 RESTful API与用户之间的通信协议统一使用HTTP(s)。HTTP协议是一种无状态的、基于请求与响应模型的应用层协议,它能够很好地支持不同类型...

    C#中的RESTful API设计:最佳实践与实现指南

    本文将探讨C#中RESTful API设计的最佳实践,包括URL设计、状态码使用、版本控制、安全性考虑以及错误处理等方面。 设计和实现RESTful API是一个需要细致考虑的过程。遵循最佳实践,如使用合适的HTTP方法、状态码、...

    Golang Gin RESTFul API with SQLite

    在这个项目中,我们将探讨Gin框架的核心特性,RESTful API设计原则,以及SQLite在Go中的应用。 Gin是一个轻量级的HTTP服务器框架,它的核心是基于Gorilla Mux,提供了一个高效的路由系统,允许开发者通过路径、方法...

    自定义机智云风格的RESTfulAPI文档

    5. **认证与安全**:如果API需要身份验证,应详细解释认证机制,如OAuth2、JWT等。 6. **版本管理**:说明如何处理API版本变化,以便开发者能够适应未来的更新。 为了实现这样的自定义风格,我们可以利用`...

    构建高效RESTful API:Golang最佳实践指南

    本文将探讨使用Golang开发RESTful API的最佳实践,包括设计原则、编码实践、安全性、性能优化等方面。 使用Golang开发RESTful API时,遵循最佳实践可以提高代码的可维护性、安全性和性能。从设计API开始,到编码、...

    spring security+jwt 实现 restful api格式.

    在本案例中,我们将探讨如何利用Spring Security集成JWT来实现RESTful API的认证与授权。首先,我们需要了解RESTful API的基本原则,即通过HTTP方法(如GET、POST、PUT、DELETE等)和资源URL来操作数据。 1. **JPA...

    Hands-On RESTful API Design Patterns and Best Practices

    4. 安全性设计:包括如何使用HTTPS来保证数据传输安全,以及如何在API中实现身份验证和授权。 5. API版本管理:随着业务需求的变化,API的版本管理是不可避免的。书中可能会探讨如何在不影响现有用户的情况下,平滑...

    Go-从任何PostgreSQL数据库提供RESTfulAPI

    标题 "Go-从任何PostgreSQL数据库提供RESTfulAPI" 暗示了我们将探讨如何使用Go编程语言构建一个服务,该服务能够通过RESTful接口暴露PostgreSQL数据库中的数据。Go是一种高效、轻量级的开源语言,常用于构建网络服务...

    WAF-Restful API接口说明1

    在本文中,我们将深入探讨一个与WAF(Web Application Firewall)虚拟化版本相关的Restful API接口,主要涵盖用户管理和业务口IP配置。 ### 1. 接口约定 在WAF的Restful API设计中,接口通常遵循以下约定: - **...

    Java RESTful API标准,桑坦德开发周.zip

    7. **安全考虑**:RESTful API应考虑安全性,例如使用HTTPS进行加密传输,认证(如OAuth2.0或JWT)和授权机制,以及防止攻击如CSRF(跨站请求伪造)和XSS(跨站脚本)。 8. **错误处理**:良好的API设计会提供结构...

    Spring CXF Restful 实例

    7. **安全性考虑**:在生产环境中,我们需要考虑API的安全性,可能需要实现身份验证和授权。Spring Security可以与Spring CXF很好地集成,提供基于角色的访问控制和OAuth2支持。 8. **监控和日志**:为了监控服务...

    基于Python Flask的简易RESTful API接口,可实现基本的前后端分离.zip

    8. **安全性考虑**:在实际应用中,还需考虑API的安全性,如认证授权、防止跨站请求伪造(CSRF)和跨站脚本攻击(XSS),可以使用Flask-JWT或Flask-HTTPAuth等扩展实现。 这个项目不仅涵盖了Flask和RESTful API的...

    PhpBoot专为开发RESTfulAPI设计的PHP框架

    - **自动数据验证**:基于注解的方式,可以方便地对请求参数进行验证,提高数据安全性。 - **ORM支持**:内置了强大的ORM(对象关系映射)系统,支持MySQL、SQLite等多种数据库,使数据库操作更加简单。 - **...

    RESTful Web API Design with Node.JS - Second Edition

    - 如何处理RESTful API中的身份验证和授权问题。 - API版本管理的最佳实践。 - 性能优化和安全措施。 RESTful API设计的标准通常与HTTP协议紧密相关,了解HTTP协议的基础知识对于设计和实现高质量的RESTful API至关...

    Python技术的Web框架与RESTful API开发指南.docx

    - **身份验证**:确保API的安全性,防止未授权的访问。 - **性能优化**:针对高并发场景下的性能优化措施,如缓存策略等。 #### 其他Python Web框架 除了Django和Flask之外,还有一些其他的Python Web框架也值得...

    RestfulApi:使用内置内存模型实现Restful API

    6. **安全考虑**:在生产环境中,我们还需要考虑API的安全性,比如使用OAuth2进行身份验证和授权,使用HTTPS确保通信安全,以及防止SQL注入和跨站脚本攻击。 7. **性能优化**:内存模型的效率取决于数据结构和算法...

    使用SDK调用京东云的restful api.7z

    在IT行业中,调用云服务API是常见的操作,特别是在开发基于云计算的应用时。...记得在实际开发中,始终遵循最佳实践,确保代码的健壮性和安全性。同时,保持对京东云API更新的关注,以便及时利用新的功能和服务。

Global site tag (gtag.js) - Google Analytics