最近这段时间,一直都在和web服务打交道。自己项目组的系统需要别的项目组提供服务接口;别的平台(手机)平台又需要我们这边给它们提供接口。实现、调用、接口文档都有所涉及。从中我发现一个非常重要的问题——安全,这是一个被严重忽略的问题。
我认为在网络这个充满敌意的大环境下,应用和服务的安全性,是一个不得不重视的问题。去年年底的CSDN账号泄露以及口令明文的事件,至少给了企业两个最基本的警示:(1)不要等到出现问题之后,才知道要去挽救,在这个浮躁的社会氛围下,出现哪怕不是什么大问题,都会被群起而攻之;(2)服务的提供方应该认识到安全的重要性。本文参考OAuth协议的工作原理,给出了我个人觉得更为安全的服务认证和授权方式。一家之谈,欢迎各位提出宝贵意见。
几个项目组对于web服务的处理方式:
(1)仅仅是一个简单的明文key,用来标识属于哪个平台;
(2)服务提供方和调用方协商一种验证码的生成规则,服务的调用方携带用户id以及生成的验证码。在服务提供方一端有个验证的方式,如果按照同样的规则生成出相同的验证码,则认为调用方是合法调用者
简单的谈谈这两种方式吧,其实第一种没什么好谈的。它只是用了一个标识符,标识服务的调用方来自哪个平台,然后在它方法中表明应该走入哪个分支,这显而易见。还有一个我觉得没什么好谈的就是,它简直就是个“肉鸡”,甚至连“肉鸡”都算不上。只要你知道URL,想干嘛干嘛去吧;第二种方式,不得不说至少比第一种方式高级得多。它至少仿照了类似数字签名的做法。但不得不说,还是有些简单并直接了。并且,要知道只要基于了同一种生成验证码的规则(注意这里并不是hash散列算法),那么它的灵活性和随机性就会降低。有一种比较简单而有效的攻击手段——DOS(拒绝服务),上面两种方式都无法逃过这样的攻击。原因是:
(1)URL是定死的,或者很长一段时间才会改变为另一种形式的,但在服务端并没有关于对来自同一个IP,在一段时间内访问次数的限制
(2)没有对调用方进行认证
对于采用HTTP GET形式的Web Service调用都会有这些安全问题。后台引用的调用方式也难以幸免于难,因为它们本质上都是一样的。其实,一方需要另一方提供服务,这种场景在互联网中早已司空见惯。新浪、腾讯、人人、网易等开放平台都是服务的提供者,它们是如何来保证服务的安全性以达到保证平台用户资源的安全?没错,它们几乎都是使用——OAuth这种认证和授权协议。
OAuth协议简介
具体的文字解释,参见wiki——OAuth
应用场景:
请求过程示意图:
项目目前对于web服务【web service/web page】的调用场景:
OAuth照搬?
OAuth的认证和授权过程中,通常都有一步需要用户授权的过程,也就是需要将用户引导到第三方服务提供者的授权页面(通常需要填写用户名和密码),并引导用户完成授权。在系统中,并不适合引入这样的交互模式。因为我们现在的系统从第三方提取数据对用户来讲是透明的,用户登录我们的系统,并不知道,我们的数据是来自第三方提供的。所以这极其影响用户体验。并且,参照资源的重要级别,并不是所有服务都需要享受这么机密的待遇(从Oath授权可以看到,需要多次的“握手”,也就是需要来回HTTP请求好几次),有时资源重要性是需要考虑的一个方面,而有时保证服务正常提供、提供服务的服务器正常运转则更为侧重。
如何兼顾安全、性能?
下图展示了本人对于兼顾安全以及性能的设想:
对于步骤说明:
第一次交互称之为:握手(也就是认证和授权的过程),由于这些服务本质上只对已知系统的特定用户开放,而非互联网应用的开放级别。所以这里省去了第一步验证客户端身份,获取Request Token的过程(或者称之为合二为一)。
步骤1:请求方采用HTTPS协议,封送能够认证调用方合法身份。这里封送什么内容呢?可以是服务提供方分配的用户名或密码对,可以是类似于上面的验证码,还可以是提供方公开的密钥。以上这些针对公共资源服务就足够了,对于类似微博那些设计到私有用户的资源,需要能够提供服务方用户检索特定资源的标识(很明显这些标识在服务调用方必须已知,比如userId等XXXID,如果不得不需要,可以在用户注册服务调用方系统的时候自行填写)。
这里你可能有一个疑问,公共资源就算了,受限资源为什么不需要用户在服务提供方平台的密码?这里还是涉及到信任级别的问题,我认为这确实是一个需要权衡的问题。或者说需要视特定应用场景以及资源的保护级别而定。上面提供的那些认证信息(包括XXXID,服务提供方会在特定的数据表中检索,以再次验证请求的合法性),足以表明服务的调用方确实是可信的,对于保护级别不是特别高(特别是应对公司内部,系统与系统之间的交互场景),最重要的是检索数据的服务而言,就可以允许调用方获取它想提取的信息了。当然如果,确实需要得到资源拥有者的授权,那么把用户定向到服务提供者的授权页面,也未尝不可。
步骤2:返回服务调用方Access Token.这是关键的一步。与开始我们谈到的我们既有的两种“验证方式”根本的不同点在于——服务提供者能够控制局面。这里可以实现各种不同的安全机制,限制访问时间,限制访问次数,限制IP在某一时间段内的访问次数等等。你可以在服务提供程序中,对于前来握手的服务调用方的信息进行维护,如:
采用访问者的ip作为key ,服务端生成的一串accsee token作为value,在服务提供端进行维护。当然,你可以定义一个结构:
以进行更合理的控制并作日志记录,至于怎么维护这个结构,在内存中还是持久化到数据库,这个不是这篇的话题。
步骤2的输出就是访问令牌当然你也可以加上一个刷新令牌(这个是可选的,主要是为了在一次会话过期后,调用方可以拿着刷新令牌,直接换取一个新的访问令牌,而不需要重新认证,当然你也可以选择让调用方重新认证。
第二次交互:服务的请求和应答,这里就没有什么特别的了。
步骤3:调用方拿着服务提供方授予的access token或者用户检索受限资源的XXXID,就可以请求服务了(只是普通的http请求)。这里,局面就可以完全被服务调用方hold住,它可以对IP和Access Token进行验证,要是有必要,也可以对会话是否过期,或者一段时间内的访问次数进行验证,而无需担心恶意中间人的重放或DOS攻击。因为服务方维护了认证过的调用方的access token以及IP。
步骤4:应答请求。
总结
这里参考了OAuth协议的工作原理,并加以精简以适应某些系统对系统提供服务的场景。再次声明,这里只是在安全和性能之间找了一个平衡点,使得你的服务应用更为坚固。如果你想要更为安全的做法,可以完全参照OAuth的设计,强制要求用户进行授权(上面已经解释了应该如何处理)。
无论如何,对于这种共享数据之类的服务,协商和人为交互的频度还是比较大的,并且效率不是太高。有没有从根本上解决这种问题的办法?有,那就是不提供这些服务。那应该怎么办?下一篇推崇——浅谈企业业务数据的整合。敬请期待!
分享到:
相关推荐
第十七章 OAuth2集成——《跟我学Shiro》 - 开涛的博客 - IT...第1页 共13页本文把授权服务器和资源服务器整合在一起实现。依赖此处我们使用a
OAuth2.0协议原理与实现
51cto购买的视频中的讲解ppt 主要讲解oauth2的协议理论,没有demo。
oauth2.0协议的认证原理,适合初学者使用
OAuth2.0原理
详细讲解OAuth2.0的基本原理及其应用,希望与大家一起交流,共同进步。
OAuth认证协议原理及使用方法 OAuth认证协议原理及使用方法
RFC 6749 OAuth 2.0 授权框架 (正式版中文翻译,PDF)
基于 Spring Cloud Hoxton 、Spring Boot 2.2、 OAuth2 的RBAC权限管理系统 基于数据驱动视图的理念封装 Ant Design Vue,即使没有 vue 的使用经验也能快速上手 提供 lambda 、stream api 、webflux 的生产实践 ...
独立的授权服务器,资源服务器,客户端单点登录系统。 采用Oauth2进行token认证,模拟用户信息进行登录。
OAUTH认证授权的流程进行初步认识。其实,简单的来说,OAUTH认证授权就三个步骤,三句话可以概括: 1. 获取未授权的Request Token 2. 获取用户授权的Request Token 3. 用授权的Request Token换取Access Token
Oauth 原理大揭露,OAuth开发文档
OAuth2.0安全案例回顾,为技术人员提供参考
NULL 博文链接:https://zhaoshijie.iteye.com/blog/2204395
描述了oauth2的原理(不含代码,如需demo请联系3546766954@qq.com),简单介绍了oauth2四种验证方式
通用RBAC权限设计及其数据权限和分库分表 支持服务限流、动态路由、灰度发布、 支持常见登录方式, 多系统SSO登录 基于 Spring Cloud Hoxton 、Spring Boot 2.3、 OAuth2 的RBAC权限管理系统 提供对常见容器化支持 ...
在整理大部分同学的需求时候,迫切需要一个小而专的微服务系统。 全面兼容Spring Cloud 最新GA版本 Spring Boot 2.0.8.RELEASE 、Spring Cloud Finchley.SR2 、Spring Security OAuth2 1. 减少中间件依赖 2.0 ...
系统说明:基于 Spring Cloud 2021 、Spring Boot 2.6、 OAuth2 的 RBAC 权限管理系统 基于数据驱动视图的理念封装 element-ui,即使没有 vue 的使用经验也能快速上手 提供对常见容器化支持 Docker、Kubernetes、...
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、...