当前位置: 首页 > news >正文

Authentication和Authrization(上)

两个案例

第一个案例是几个月前,我收到一位朋友的邮件,邀请我加入一个叫ShoppyBag的网站。我去看了,没想到注册后就让我登录GMail帐号,并且GMail提示我该网站需要访问我的通讯录,于是我当即就中断了注册过程。

对于这类需要访问我的邮箱通讯录的网站我都是非常厌恶的,无数的垃圾邮件就是来自于它们。它们通过访问你的邮箱通讯录,然后向你的联系人们发邮件,然后迅速扩大了用户量可以向VC骗钱,而用户的隐私就这样被卖掉了,更不用说那些不请自来的垃圾邮件。

当然,虽然我中断了注册过程,但用户是已经注册成功了,只是访问网站时还会不时地提示我登录GMail。仔细看了它的提示内容后,发现有一行小字写着:

Your email address book contacts will be imported to your ShoppyBag Address Book.
ShoppyBag will not store your email login information or contact anyone without your permission.

我当然知道这种登录方式这个网站不会取得我的邮箱登录信息,它也可以假装未经授权不向我的联系人发邮件,但是我完全不想把我的通讯录COPY一份给它,因为只要那东西在它手上,我就不能保证它会拿来干什么。

之后还收到别的朋友也发来这个网站的邮件,而且在People You May Know里也看到很多熟人,不知道其中有多少人是中招的多少人是相信了这个网站的。

总之我是不信任这类网站,并且不会把通讯录授权给它们的。反正对这类SNS我也没什么兴趣。

这 个网站之所以可以取得用户的GMAIL通讯录,但是又不需要知道用户的密码,就在于它使用了GMAIL的一个授权(Authorization)功能的 API,当用户被定向到GMAIL登录页面时,用户选择允许以后,这个网站就可以通过GMAIL的通讯录API取得用户的通讯录了。

第二 个 案例也是几个月前在豆瓣小组,有人发布了一个他自己做的网站,因为要注册,我懒得去看,后来他说支持GOOGLE帐号登录,我就想去看看。结果是一登录GOOGLE 帐号就提示说这个网站要访问我的GMAIL通讯录。基于前所说的原因,我就把这个帖子给封了,那个楼主就发来豆邮兴师问罪。说是第三方用GOOGLE帐号 登录就是会这样的,但是很不幸我刚好最近也研究过这一块东西,知道并非如此。

所以我们需要先搞清楚一个问题,那就是认证和授权的区别。

Authentication和Authorization的区别

As we know,用户管理功能是大部分网站的基本功能,而这其中基本的基本就是用户身份验证,简单说就是登录——也就是“如何证明‘你’就是‘你’”。这就是所谓的Authentication。

用户管理的另一个基本部分(这个部分虽然基本,但不是必须的)则是权限管理——也就是“‘你’可以干什么”。这就是所谓的Authorization。

前 面两个例子中,第一个例子就是一种第三方Authorization,它试图让用户授权给它访问用户通讯录的权限。第二个例子则是错误地使用了 Authorization进行Authentication操作——当然,这里是以善意的角度来看这个网站,要是从恶意的角度上说,也可能它就是要用这 种方式来获取用户通讯录。

传统的应用中,Authentication和Authorization都是由应用程序自己进行处理的(即集 成 认证),相对来说问题少一些。只是对于应用开发者来说比较麻烦,每做一个应 用就需要把这一套全实现一次——Copy&Paste也是体力活啊。更麻烦的是对于用户来说,每到一个网站就要把注册流程走一遍,还要碰上用户名 冲突,担心密码安全之类的问题——很多网站对我来说最常用的功能就是:取回密码。囧

集成登录后的权限管理自然也是集成处理。

于是有了单点登录(SSO)——现在这已经是大网站的标配了,都是通过一个passport的统一登录点登录网站下的各个子功能。以及第三方登录——比如现在流行的用twitter或facebook帐号登录(国内对应的是用开心人人之类的帐号登录)。

单点登录后,具体应用取得登录信息,之后的权限管理也是应用程序自己处理,passport应用一般是不管的。

当然,最开放的还是分布式登录,比如OpenID。其实关于OpenID的话题,我早在06年就写过一篇《身份验证——谈谈OpenID》。 现实的发展跟我的预期差不多——OpenID并没有能够得到广泛的应用,最近甚至有消息说,已经有一些网站取消了对OpenID的支持,因为用的人太少 了。目前OpenID协议用得多的话也只是用于第三方登录(相当于单点登录的一种)而不是分布式登录——比如用Google帐号登录其它网站。

这个时候就需要注意Authentication和Authorization的问题了——你一定不希望别人用你的GMAIL帐号给你的朋友发垃圾邮件甚至邮件吧?如果你是一个第三方应用开发者,你的用户当然也不希望。

以上三种方式的各自优缺点已经在前文里说过了,这里不再讨论。

Authentication 和Authorization两个概念相关性很高,很容易搞混,很多时候这也没什么问题,特别是集成认证的情况下,反正全都在统一控制之下。但是对于第三 方认证的情况下就需要考虑更多一些,最好还是把两种情况分清楚比较好。因此这里主要讨论第三方认证的情况。

第三方认证有很多方式,一般分 为 两类:认证方提供专有的API供认证,比如Microsoft Passport,早年Google也有Account API供Authorization使用(当时并不提供Authentication服务),提供了对日历和通讯录等的授权访问支持;另一类是采用开放方 案,这是目前的主流,最常用的就是OpenID和OAuth。

登录及认证流程

在整个登录认证过程中,可以分成几个参与方:一个是认证提供方(Provider),另一个是认证使用方(Consumer),介于其中的就是被认证的用户(User)。除此之外,还有一个对象,那就是服务(Service),即用户登录后所需要使用的功能——这才是用户登录的目的。之所以要单独提到这个Service,是因为它可能是由Consumer提供,也可能有一部分是由Provider提供。如果Provider完全不提供Service,那Provider就是一个纯粹的Authentication提供方,如果Provider同时还提供部分Service,比如GOOGLE提供的通讯录、日历等的服务给Consumer,那么Provider同时还是一个Authorization提供方。

其实通常的分歧也就是出在后一种情况下。因为通常对于用户的权限管理都是集成在提供Service的Consumer端,登录只是一个Authentication过程,单点登录(SSO)就是一个典型的情况。只有在第三方登录的情况下才会发生需要认证方提供部分Service,这时才会有部分Authorization工作“外包”的情况。因此导致二者的混淆与误用。

其实在整个过程中,User的目的只是为了使用Consumer提供的Service,验证身份及权限只是安全性的需要。

在一个典型的第三方Authentication过程中,User向Consumer请求某个Service,Consumer就向Provider查询User的身份,User通过密码等方式向Provider验证身份,并允许Provider将验证结果通告Consumer,Consumer在取得Provider的验证通过结果后,向User提供相应的Service。

而一个典型的第三方Authorization过程中,User向Consumer请求某个Service时,这个Service可能还需要第三方提供一些辅助的Service,比如通讯录,这时Consumer就要向Provider请求访问User的这个Service,Provider则向User提示Consumer的这个请求,User通过密码登录Provider并同意这个请求后,Provider把授权结果返回给Consumer(通常是通过返回一个Token),Consumer这时不但验证了User的身份,同时还得到了它所需要的User的某些Service访问权限,之后它就可以以这个User的身份访问Provider的相关Service了。

(上面本来想配两张图的,但是嫌麻烦,懒得画了-_-)

OpenID就是解决前一种场景,而OAuth则是解决后一种情况。

(待续)

相关文章:

  • std::bind()图解
  • perl概述
  • Thinkphp中在本地测试很好,在服务器上出错,有可能是因为debug缓存的问题
  • perl入门--语法和结构(1)
  • 6月15日云栖精选夜读:阿里配管专家解读:如何最优成本搭建非标准的iOS构建集群...
  • Android下实现电话号码归属地的查询
  • 【转】设计模式总结
  • 21、Java并发性和多线程-Java中的锁
  • 让我有勇气热烈拥抱最后的结局—leo鉴书(14)
  • c++ -- 面向对象程序设计
  • Android下使用Http协议实现多线程断点续传下载
  • HDOJ 5296 Annoying problem LCA+数据结构
  • 程序员面试、算法研究、编程艺术、红黑树等5大系列集锦与总结
  • Python3.x--文件读写与list
  • 毕业面试 | 如何准确一分钟介绍你自己?
  • 【Linux系统编程】快速查找errno错误码信息
  • Android 控件背景颜色处理
  • CentOS7 安装JDK
  • centos安装java运行环境jdk+tomcat
  • crontab执行失败的多种原因
  • C语言笔记(第一章:C语言编程)
  • E-HPC支持多队列管理和自动伸缩
  • es6(二):字符串的扩展
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • node和express搭建代理服务器(源码)
  • php的插入排序,通过双层for循环
  • React-redux的原理以及使用
  • Redux 中间件分析
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • - 概述 - 《设计模式(极简c++版)》
  • 机器学习 vs. 深度学习
  • 如何学习JavaEE,项目又该如何做?
  • 使用API自动生成工具优化前端工作流
  • 一、python与pycharm的安装
  •  一套莫尔斯电报听写、翻译系统
  • 移动端唤起键盘时取消position:fixed定位
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 找一份好的前端工作,起点很重要
  • 自动记录MySQL慢查询快照脚本
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • # include “ “ 和 # include < >两者的区别
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #宝哥教你#查看jquery绑定的事件函数
  • ${ }的特别功能
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (2022 CVPR) Unbiased Teacher v2
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (五)网络优化与超参数选择--九五小庞
  • (小白学Java)Java简介和基本配置