如何实现RESTful Web API的身份验证

 

最近想拿一个小项目来试水RESTful Web API,项目只有几个调用,比较简单,但同样需要身份验证,如果是传统的网站的话,那不用说,肯定是用户名+密码在登录页获得登录Token,并把登录Token记在Cookie和Session中作为身份标识的这种方式,但现在不同了,关键是RESTful,这意味着我们设计出来的这些API是无状态的(Stateless),下一次的调用请求和这一次的调用请求应该是完全无关的,也就是说,正宗的RESTful Web API应该是每次调用都应该包含了完整的信息,没错,包括身份信息!

 

那如何确保安全?传输时给密码做MD5加密?得了吧!这样做只能让你自己感觉“安全”点,其实没什么任何用处,利用现在的技术(有种叫什么Rainbow Table啥的来着?本人外行,不是很懂)很快就能算出明文密码了,而且如何防止挟持和重发攻击?

 

也许你想到了,SSL,如果你打算采用SSL,请忘记一切自行设计的加密方案,因为SSL已经帮你做好了一切,包括防止监听,防止挟持,防止重发……一切都帮你考虑好了,你大胆地把明文密码写在你的包中就OK了,我向你保证没问题。

 

但SSL的缺点是服务器端配置相对有点复杂,更关键的就是客户端对此支持可能不好,那你考虑一种自己的加密方法,有木有?我这里提供一种方法,思路来自于:http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/,我只是把上面的内容中整理了一下变成了我的方法。(传说中的剽窃?呵呵)方法描述如下:

 

假设有一个用户,用户名是guogangj,密码是123456(呃……这也能叫密码?)

 

他要GET http://test.com/api/orders/

 

于是把 http://test.com/api/orders/这个URL和一个新生成的GUID拼在一起,再用123456这个密码执行对称加密,生成的密文为XXXXOOOOXXXXOOOO(假设而已)

 

数据包中带上用户名guogangj和XXXXOOOOXXXXOOOO这个密文,发送给服务器

 

服务器收到包后,根据guogangj这个用户名到数据库中查找到123456这个密码

 

服务器使用123456这个密码来解密XXXXOOOOXXXXOOOO这个密文,得到了明文,即http://test.com/api/orders/这个URL和前面由客户端生成的那个GUID

 

服务器到一个全局的集合中查找这个GUID,看看是否已经存在,如果存在,则验证不通过,如果不存在,就将其放入这个集合中。这是为了避免重发攻击。这个全局的集合会越来越大,所以还要定期清理。

 

服务器再比对解密出来的URL和用户真实请求的URL是否一致,如果一致,那么认为这是合法用户,验证通过!

 

这是大致过程,如果数据库里找不到该用户,或者解密错误,都被认为验证不通过。以下是一些改进:

 

数据库中的密码最好做一下摘要(MD5之类的),客户端对应地也要做一下。

 

在生成密文的时候可以考虑加入另外一些不希望被明文传输的敏感内容,甚至可以加入IP地址,并在服务器端验证。

 

并非每次都要真正去数据库里拿一次用户信息,也许你有更好的办法,比如一个简单的缓存(不过需要处理缓存更新的问题),或者当你的系统大到一定程度的时候,你考虑使用统一的服务来获取用户信息,这就不是缓存那么简单了,里面的文章很多,我相信现在大规模的门户网站都有自己的一套复杂的机制,所以表明上看RESTful Web API很“低效”,但这种RESTFul的思路和模式却在实际中有很大的可塑性和威力。

 

这种方法应该足够安全了!

 

密码根本没有在网络上传输,密文采用的是非验证的对称加密,没有密钥就无法逆转,URL验证避免了传统的身份挟持攻击(即拦截一个用户的包并冒充此用户来访问其它的资源,即便无法破解用户密码), 再用GUID来避免了重发攻击,唯一需要担心的是用户泄露了自己的密码。

WebApi验证的更多相关文章

  1. webApi 验证basic-authentication认证的资源的各种语言的实现

    HTTP Basic authentication (BA) 是一个基于http请求的,简单验证.详细资料:https://en.wikipedia.org/wiki/Basic_access_aut ...

  2. [开源]快速构建一个WebApi项目

    项目代码:MasterChief.DotNet.ProjectTemplate.WebApi 示例代码:https://github.com/YanZhiwei/MasterChief.Project ...

  3. 为IIS Host ASP.NET Web Api添加Owin Middleware

    将OWIN App部署在IIS上 要想将Owin App部署在IIS上,只添加Package:Microsoft.OWIN.Host.SystemWeb包即可.它提供了所有Owin配置,Middlew ...

  4. 一站式Web开发套件BeetleX.WebFamily

    BeetleX.WebFamily是一款前后端分离的Web开发套件,但它并不依赖于nodejs/npm/webpack等相关工具:而使用自身实现的方式来完成前后端分离的Web应用开发:套件以组件的方式 ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(66)-MVC WebApi 用户验证 (2)

    系列目录 前言: 回顾上一节,我们利用webapi简单的登录并进行了同域访问与跨域访问来获得Token,您可以跳转到上一节下载代码来一起动手. 继续上一篇的文章,我们接下来演示利用拿到的Token来访 ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1)

    系列目录 前言: WebAPI主要开放数据给手机APP,其他需要得知数据的系统,或者软件应用,所以移动端与系统的数据源往往是相通的. Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能, ...

  7. webapi - 模型验证

    本次要和大家分享的是webapi的模型验证,讲解的内容可能不单单是做验证,但都是围绕模型来说明的:首先来吐槽下,今天下午老板为自己买了套新办公家具,看起来挺好说明老板有钱,不好的是我们干技术的又成了搬 ...

  8. WebApi基于Token和签名的验证

    最近一段时间在学习WebApi,涉及到验证部分的一些知识觉得自己并不是太懂,所以来博客园看了几篇博文,发现一篇讲的特别好的,读了几遍茅塞顿开(都闪开,我要装逼了),刚开始读有些地方不理解,所以想了很久 ...

  9. 微信企业号开发(1)WebAPI在回调模式中的URL验证

    微信回调模式的官方文档. 开发语言:C#(微信相关功能代码可以从官网下载) 首先,必须要明确几个参数,这几个参数在微信企业号中,每次调用都会使用到. 1.msg_signature:签名(已加密,加密 ...

随机推荐

  1. Traefik HTTPS 配置

    参考 add-a-tls-certificate-to-the-ingress Entry Points Definition 使用traefik作为ingress controller透出集群中的h ...

  2. java static学习

    原创,转载请注明来源sogeisetsu的博客园 static,在类里面定义公共的属性,它可以统一修改,并只占一个内存.从而达到方便修改和少占内存的目的 先放上代码,您可以先越过代码,看后面的讲解内容 ...

  3. nginx 代理服务

    1.nginx反向代理服务 location ~ /test_proxy.html$ { proxy_pass http://127.0.0.1:8080;(代理访问127.0.0.1:8080) } ...

  4. AtCoder Grand Contest 033 题解

    传送门 我比赛的时候怕不是在睡觉啊-- \(A\ Darker\ and\ Darker\) 我是不是想得太复杂了--根本没必要像我这样做吧-- 首先问题可以转化成令\(p_{i,j}\)表示到\(( ...

  5. 每天一道Rust-LeetCode(2019-06-02)

    每天一道Rust-LeetCode(2019-06-02) Z 字形变换 坚持每天一道题,刷题学习Rust. LeetCode原题 Z 字形变换 题目描述 将一个给定字符串根据给定的行数,以从上往下. ...

  6. IIS 报错 Cannot open database "test4" requested by the login. The login failed. Login failed for user 'IIS APPPOOL\test1'.

    报错: Cannot open database "test4" requested by the login. The login failed. Login failed fo ...

  7. dfs的两种处理方法

    方法一: 对于源点s,初始化vis[s]=1,并且在dfs之后vis[s]=1,为下一次调用做准备 .对于dfs递归中的寻找后继的循环体,入栈出栈语句写在循环内. 模板: //调用 vis[s]=; ...

  8. suse12.2构建samba

    1:添加用户 useradd wangjunhui -d /home/wangjunhuipasswd wangjunhui 2:配置samba smbpasswd -a wangjunhui vi ...

  9. [算法模版]Link-Cut-Tree

    [算法模版]Link-Cut-Tree 博主懒本博客只对现有博客进行补充,先直接放隔壁链接. FlashHu-LCT总结 Menci-LCT学习笔记 make-root操作 make-root操作用于 ...

  10. Java实现添加压缩文件

    package junittest; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStr ...