- 鉴权
鉴权(authentication)是指验证用户是否拥有访问系统的权利。传统的鉴权是通过密码来验证的。这种方式的前提是,每个获得密码的用户都已经被授权。在建立用户时,就为此用户分配一个密码,用户的密码可以由管理员指定,也可以由用户自行申请。这种方式的弱点十分明显:一旦密码被偷或用户遗失密码,情况就会十分麻烦,需要管理员对用户密码进行重新修改,而修改密码之前还要人工验证用户的合法身份。
为了克服这种鉴权方式的缺点,需要一个更加可靠的鉴权方式。目前的主流鉴权方式是利用认证授权来验证数字签名的正确与否。
逻辑上,授权发生在鉴权之后,而实际上,这两者常常是一个过程。
要解释什么是鉴权之前,我们先看看如果没有鉴权会怎么样?
如果没有鉴权功能,移动用户可随意接入和使用任一无线网络,运营商的利益得不到保障,同时,用户的安全也会受到威胁。移动通讯网络发展之初,就考虑并解决了这个问题:采取用户鉴权的方式来识别出非法用户。用户鉴权,是对试图接入网络的用户进行鉴权,审核其是否有权访问网络。通过用户鉴权可以保护网络,防止非法盗用;同时通过拒绝假冒合法客户的“入侵”而保护该网络中的客户。
然而,道高一尺魔高一丈。相信大家听过或者亲身经历这样的事件吧。某人的手机上收到“恭喜你获得一等奖,请预付税费”、“公司出售各类发票”之类的非法诈骗、推销短信,因而上当受骗,损失了钱财。有的甚至显示是110发来的。这种情况,可能是用户接入了假冒的网络,所以,用户也需要对网络进行鉴权。
鉴权包括两个方面:
用户鉴权,网络对用户进行鉴权,防止非法用户占用网络资源。
网络鉴权,用户对网络进行鉴权,防止用户接入了非法的网络,被骗取关键信息。
这种双向的认证机制,就是AKA(Authentication and Key Agreement,鉴权和密钥协商)鉴权。
除了AKA鉴权,也可以使用其它鉴权方式。在IMS AKA鉴权广泛实施之前,或在特定的条件下(例如通过固定网络ADSL连接方式接入IMS),可以使用HTTP摘要鉴权等其他鉴权方式。
3G UMTS(Universal Mobile Telecommunication System,通用移动通讯系统)、EPS(Evolved Packet System,演进的分组系统)、IMS(IP Multimedia Subsystem,IP多媒体子系统)网络都采用了AKA双向鉴权机制,鉴权原理也大致相同。而2G网络,只有用户鉴权,无网络鉴权。
鉴权过程
我们以3G UMTS网络鉴权为例,看看网络和用户分别是怎么鉴权的。
1、当用户购机入网时,运营商将IMSI(International Mobile Subscriber Identity,国际移动用户标识)和用户鉴权键Ki一起分配给用户,同时将该用户的IMSI和Ki存入AUC(Authentication Center,鉴权中心),这样鉴权参数信息存储在手机的USIM(UMTS Subscriber Identity Module,UMTS用户身份模块)卡和AUC中。
2、VLR(Visitor Location Register,拜访位置寄存器)从AUC获得用户的鉴权数据,MSC(Mobile Switching Center,移动交换中心)/VLR从鉴权数据中选取一组未使用过的鉴权参数。MSC/VLR向手机发起鉴权请求。请求消息中携带所选取的鉴权参数中的RAND、AUTN和CKSN参数。
3、手机中的USIM根据收到的RAND和自己保存的IMSI、Ki一起计算出XMAC,与从网络侧收到的AUTN中的MAC值进行比较。
4、如果相同,继续验证接收到的AUTN中序列号SQN是否在有效的范围内。序列号SQN的设置是为了防止他人冒充网络,利用截获的、旧的鉴权参数AUTN欺骗用户。
5、如果SQN有效,则认为这是个合法网络,网络鉴权成功。手机计算出RES,并将RES发送给MSC/VLR/SGSN。否则若发现SQN值无效时,手机会向网络报错并且触发网络与手机间的SQN重新同步过程。
6、如果SQN同步失败或者MAC值不同,则网络鉴权失败。
7、MSC/VLR将自己用RAND、IMSI和Ki算出的XRES与手机返回的RES进行比较。如果相同,则认为用户合法,用户鉴权成功,网络允许手机接入;否则认为用户不合法,用户鉴权失败,拒绝为其服务。
鉴权时机
移动网络对鉴权时机的要求为:
2G、3G网络中,鉴权发生在开机、呼叫、位置更新以及在补充业务的激活、去活、登记或删除操作之前。
2G网络中,运营商都是启用的“按比例鉴权”方案。
3G网络中,用户首次接入网络必须鉴权,此后启用“按比例鉴权”方案。
IMS网络中,网络可以通过注册或重注册过程,在任何时候对用户进行鉴权。 [2]
鉴权方式
我们常用的鉴权有四种:
1、HTTP Basic Authentication
2、session-cookie
3、Token 验证
4、OAuth(开放授权)
一、什么是OAuth(开放式授权)
OAuth: Open Authorization
OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使用第三方触及到用户的账号信息(如用户名与密码),即第三方无需使用用户的用户名和密码就可以申请获得该用户资源的授权,因此OAUTH是安全的
使用QQ号登陆慕课网:
- 用户访问慕课网,在登录表单中点击了使用QQ登录的按钮
- 慕课网请求QQ的OAuth登录页面,用户在该页面输入QQ号和密码(此处输入Q号和密码的过程始终是在QQ的OAuth页面上完成的,该页面不属于慕课网)
- QQ的OAuth服务器检验用户输入的账号信息是否正确并把结果反馈给慕课网(反馈的结果中不包含用户的QQ号和密码,只是告诉慕课网当前用户是否登录成功)
- 慕课网接收到用户登录成功的信息之后,把用户的登录状态切换为登录成功
版本:
- OAuth 1.0 发布于2007年末
- OAuth 2.0 发布于2010年初
二、OAuth的应用场景
QQ用户授权慕课网使用其QQ账号相关的信息
获取授权后,在符合权限规则的情况下访问各种API
三、三个重要步骤分析
步骤一:请求OAuth登录页
Request Token URL :未授权的令牌请求服务地址
慕课昂请求QQ登录页面时使用的带有特定参数的URL:
除了慕课网之外还有很多第三方站点在使用QQ登录,每个站点在揭露QQ登录之前都得到QQ互联的官网注册,提交一份申请的材料,说明揭露站点的描述、站点的域名、回调地址等信息,然后QQ互联的官网会给申请使用QQ登录的站点分配一组appid和appkey,类似账号和密码,appid是唯一的,每个申请QQ揭露的站点都有一个唯一的appid,这样,对于QQ登录的服务器来说,可以通过此id来判断当前是哪个站点在请求使用QQ登录,该站点是否在QQ互联平台提交过申请材料等;慕课网在提交申请材料的时候会把回调地址预留给QQ互联的平台,服务端会对比相应的appid中预留的回调地址和提交过来的参数域名是否一样等
- 服务器的URL:https://graph.qq.com/oauth/....?....
- 对应appid:&client_id=100490398&....
- 回调地址:&redirect_uri=http://www.mukewang.com/.....
步骤二:用户使用第三方账号登录并授权
用户输入QQ号和密码不匹配,直接被QQ的OAuth服务器拒绝,重新登录;
在用户正确输入QQ号和密码,登录成功的情况下:
回调地址:&redirect_uri=http://www.mukewang.com/.....
就是告诉QQ的OAuth服务器,当用户登录成功以后,要跳转到什么地方去,并且在跳转的过程中,URL后面会带上一个加密过的参数code(http://www.mukewang.com/user/qqcallback?code=xxxxxxx...),当url跳转回慕课网指定的回调地址之后,在代码中可以获取到code
步骤三:返回登录结果
在步骤二中,慕课网拿到了一个加密过的参数code,此时,说明用户输入的QQ号和密码是匹配的,即登录成功了;但是出于安全考虑,单凭code还不能赋予第三方网站使用用户的QQ号去执行一些操作(因为在回调的过程中,code可能会被劫持),所以,为了确保code被合法的第三方服务器获取到,此时需要慕课网的服务器再次请求一个url地址:
User Authorization URL :用户授权的令牌请求服务地址
用户QQ登录授权之后需要请求的一个带有特定参数的URL:
https://xxx.qq.com/oauth/...?...
&client_id=100490398&....
&client_secret=xxxxxxxxxx&......
&code=xxxxxxxxxxx......
client_id和client_secret对应慕课网得到的一组appid和appkey,分别对应这两个参数,把他拼接到url中,最后还需要拼接上用户授权登录之后拿到的code参数(code是会过期的,有效时间都比较短,一般为10秒)
code是一个有生命周期且只可使用一次的字符串 ,慕课网的服务器在很短的时间内就要完成这个一来一回的数据交互过程,一旦超过这个code的有效时间,OAuth的服务器就会认为登录的过程中可能出现了一些安全问题,然后拒绝第三方网站继续后面的操作;如果其中有人劫持到了code,那么他必须在很短的时间内对code进行破解,并且还需要去伪造一个对应的第三方服务器请求的url,就更困难了;多了一个一来一回的数据交互,对于OAuth的服务器来说,第一,他再次检验了发起请求的第三方服务器是否是一个合法的服务器并且还会对appkey作比对;第二,检查code的合法性,查看code是否是上一个步骤发给慕课网服务器的那个code以及再次发起请求的时间是否在有效时间范围内,通过这样的一个检验来进一步提高安全性;在请求这个url之前,慕课网的服务器并不知道登录的用户的信息,只知道有一个用户使用QQ号登录了,当慕课网的服务器请求了用户授权之后的令牌请求url之后,才会得到一个响应数据,响应数据中包含了一些信息:用户具体是谁,QQ昵称、头像等一些比较基本的账号信息,慕课网的服务器就可以把这些信息写入到用户数据表中,此时,code也失效了
四、AccessToken与RefreshToken数据传输原理和生命周期
AccessToken:用户通过第三方应用访问OAuth接口的令牌:
通过慕课网把自己喜欢的课程分享到QQ空间
用户发给第三方网站的令牌
在OAuth使用的过程中,当用户授权登录完成之后,第三方站点拿到了一个当前用户的accessToken,有了accessToken就可以调用相应的API;访问开放平台的接口实质上都是通过第三方应用拼接一个特定的url来访问API的。即使连续几次访问同一个API的接口,动态拼接出来的url都有可能是不一样的。即任意一次访问API都需要重新拼接一个特定的url,而且每次都要用上AccessToken作为令牌,出于安全考虑,一般都会使用post方式发送http请求,OAuth的服务器会验证链接中的accessToken是否为合法的,把相应的数据包打包成xml或json返回给第三方的服务器。
AccessToken具有较长生命周期(10天半个月甚至更长)
只要accessToken没有过期,就可以一直使用它来访问API,如果过期了,有两种方式重新获取一个新的accessToken:
- 重新授权登录第三方站点
- 拼接User Authorization URL时带上一个布尔型的参数,指明在返回的结果中是否需要携带一个叫refreshToken的参数(刷新令牌);如果指明了需要它,就会在返回的数据中携带这个参数,(各个平台的该参数名会有差异)当accessToken快过期的时候就可以使用这个RefreshToken动态拼接一个特定的url来请求一次,就可以获取一个新的accessToken(一般在后台有定时任务的时候使用)
注:RefreshToken也有生命周期,不过这个时间就更长了,基本上是几个月到半年左右
- 初级:以Cookie作为凭证媒介
- 中级:通过JSONP实现
- 高级:通过页面重定向的方式
- 总结:使用独立登录系统
- # 附录
- 分析:SSO(单点登录) 与 OAuth2.0(授权) 的区别?
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效性,因此要点也就以下两个:
1. 存储信任
2. 验证信任
如果一个系统做到了开头所讲的效果,也就算单点登录,单点登录有不同的实现方式,本文就罗列我开发中所遇见过的实现方式。
初级:以Cookie作为凭证媒介
最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。用户登录父应用之后,应用返回一个加密的cookie,当用户访问子应用的时候,携带上这个cookie,授权应用解密cookie并进行校验,校验通过则登录当前用户。
不难发现以上方式把信任存储在客户端的Cookie中,这种方式很容易令人质疑:
1. Cookie不安全
2. 不能跨域实现免登
对于第一个问题,通过加密Cookie可以保证安全性,当然这是在源代码不泄露的前提下。如果Cookie的加密算法泄露,攻击者通过伪造Cookie则可以伪造特定用户身份,这是很危险的。对于第二个问题,更是硬伤。
中级:通过JSONP实现
对于跨域问题,可以使用JSONP实现 传送门:(如果不知道JSONP是什么?)。用户在父应用中登录后,跟Session匹配的Cookie会存到客户端中,当用户需要登录子应用的时候,授权应用访问父应用提供的JSONP接口,并在请求中带上父应用域名下的Cookie,父应用接收到请求,验证用户的登录状态,返回加密的信息,子应用通过解析返回来的加密信息来验证用户,如果通过验证则登录用户。
这种方式虽然能解决跨域问题,但是安全性其实跟把信任存储到Cookie是差不多的。如果一旦加密算法泄露了,攻击者可以在本地建立一个实现了登录接口的假冒父应用,通过绑定Host来把子应用发起的请求指向本地的假冒父应用,并作出回应。因为攻击者完全可以按照加密算法来伪造响应请求,子应用接收到这个响应之后一样可以通过验证,并且登录特定用户。
高级:通过页面重定向的方式
最后一种介绍的方式,是通过父应用和子应用来回重定向中进行通信,实现信息的安全传递。 父应用提供一个GET方式的登录接口 A (此时的父应用接口固定,攻击者无法去伪造),用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个的登录页面,用户输入账号密码进行登录。如果用户已经登录了,则生成加密的Token,并且重定向到子应用提供的验证Token的接口 B (此时的子应用接口固定,攻击者无法去伪造),通过解密和校验之后,子应用登录当前用户。
这种方式较前面两种方式,接解决了上面两种方法暴露出来的安全性问题和跨域的问题,但是并没有前面两种方式方便。安全与方便,本来就是一对矛盾。
总结:使用独立登录系统
一般说来,大型应用会把授权的逻辑与用户信息的相关逻辑独立成一个应用,称为用户中心。用户中心不处理业务逻辑,只是处理用户信息的管理以及授权给第三方应用。第三方应用需要登录的时候,则把用户的登录请求转发给用户中心进行处理,用户处理完毕返回凭证,第三方应用验证凭证,通过后就登录用户。
# 附录
分析:SSO(单点登录) 与 OAuth2.0(授权) 的区别?
oauth2.0
1、解决的是服务提供方(如:微信等)给第三方应用授权的问题
2、是一种具体的协议,只是为用户资源的授权提供了一个安全的、开放而又简易的标准。OAuth 2.0为客户端开发者开发Web应用,桌面端应用程序,移动应用及客厅设备提供特定的授权流程。
3、通俗的讲,OAuth是为解决不同公司的不同产品实现登陆的一种简便授权方案,通常这些授权服务都是由大客户网站提供的,如QQ,新浪微博,人人网等。而使用这些服务的客户可能是大客户网站,也可能是小客户网站。使用OAuth授权的好处是,在为用户提供某些服务时,可减少或避免因用户懒于注册而导致的用户流失问题
sso
1、解决的是大型系统中各个子系统如何共享登陆状态的问题
2、是一种技术,可以用cookie实现,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统
3、通常处理的是一个公司的不同应用间的访问登陆问题。如企业应用有很多业务子系统,只需登陆一个系统,就可以实现不同子系统间的跳转,而避免了登陆操作。
参考文献
传送门: 单点登录原理
传送门: oauth2详解
原文地址:https://www.cnblogs.com/yhxb/p/11514248.html