什么是OAuth2
OAuth2 是一个工业级别的开发授权协议,可以使互联网用户授权第三方网站或应用访问他们在特定网站上的信息(如个人资料、照片等),而不必向第三方网站或应用提供密码。在此之前我们使用用户名和密码的方式登录到应用,在OAuth授权协议提出了一个 “授权服务器”,经过用户授权后授权服务器向第三方应用发放一个访问令牌,这样就可以在不向第三方应用提供账号和密码的情况下,通过令牌在特定时间内访问用户存放在特定资源服务器上的资源。
OAuth2解决了什么问题
任何身份认证,本质上都是基于对请求方的不信任所产生的,我可能不信任某个站点,但是我信任微信,微博...,实质上身份认证解决了身份可信任问题.
拿QQ登录B站来讲:
在OAuth2协议中简单说可以有三方,1:我自己(用户),2:QQ(服务提供方),3:B站(客户端)
在没有登录微信的情况下,我给B站授权,因为QQ微信服务方不信任我,所以我需要先登录QQ,这样才能给我提供一些可信凭据,而QQ也不能信任每一个站点,所以对于B站而言,需要在微信上申请一个自己的第三方应用,也就是我们的id和scrit
OAuth 有四种角色
资源所有者(resource owner) 我们(普通用户)
资源服务器(resource server) QQ的后台服务器(获取账号,昵称,头像等)。
客户端(client) B站
授权服务器(Authorization Server) 认证QQ & 授权用的。
协议角色和流程
A: Client(client_id)向Resource Owne发送一个授权请求
B: Resource Owne同意授权之后就会获得一个Resource Owne的一个资源授权许可(code)
C: Client拿到授权许可(code)之后,会向Authorization Server发送一个验证,
D: 如果验证有效会给它颁发一个Token给Client
E: Client拿到这个Token之后,去Resource Server后的获取账号信息
F: Resource Server就会返回受保护的资源
拿id换code,再拿code换token
注意:非常重要的B这一步,在C中拿什么东西让Authorization Server去验证呢? 不知道,只有当确定了B这一步之后,才能确定C是拿密码,code还是Token去验证
OAuth四种授权方式
1, 授权码模式(Authorization Code Grant)
这种模式是四种模式中最安全的一种模式。一般用于Web服务器端应用或第三方的原生App调用资源服务的时候。
授权流程:
(1)资源拥有者打开客户端,客户端要求资源拥有者给予授权,它将浏览器被重定向到授权服务器,重定向时会附加客户端的身份信息
(2)浏览器出现向授权服务器授权页面,之后将用户同意授权。
(3)授权服务器将授权码(AuthorizationCode)转经浏览器发送给client(通过redirect_uri)。
(4)客户端拿着授权码向授权服务器索要访问access_token
(5)授权服务器返回令牌(access_token)
参数列表如下:
参数 | 解释说明 |
---|---|
client_id | 客户端接入标识。 |
response_type | 授权码模式固定为code。 |
scope | 客户端权限。 |
redirect_uri | 跳转uri,当授权码申请成功后会跳转到此地址,并在后边带上code参数(授权码)。 |
refresh_token
- 因为Token会过期所以又提出一个refresh_token
2, 简化模式(Implicit Grant)
简化模式 implicit 不支持refresh token 这种没有获取code的步骤。请求就给token、 没get到这个的优势
简化授权流程
(1)资源拥有者打开客户端,客户端要求资源拥有者给予授权,它将浏览器被重定向到授权服务器,重定向时会附加客户端的身份信息。
(2)浏览器出现向授权服务器授权页面,之后将用户同意授权。
(3)授权服务器将授权码将令牌(access_token)以Hash的形式存放在重定向uri的fargment中发送给浏览器。
fragment 主要是用来标识 URI 所标识资源里的某个资源,在 URI 的末尾通过 (#)作为 fragment 的开头, 其中 # 不属于 fragment 的值。
简化流程
(A) 客户端通过指示资源所有者的授权端点的用户代理。 客户端包括其客户端标识符、请求的作用域、本地状态和授权服务器将向其发送一旦授予(或拒绝)访问权限,用户代理就会返回。
(B) 授权服务器对资源所有者进行身份验证(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。
(C) 假设资源所有者授予访问权限,则授权服务器使用前面提供的重定向 URI。 重定向 URI 包括URI 片段中的访问令牌。
(D)用户代理遵循重定向指令,通过使对 Web 托管的客户机资源的请求(不包括每个 [RFC2616] 的片段)。 用户代理保留本地碎片信息。
(F) 用户代理执行 Web 托管提供的脚本本地客户机资源,用于提取访问令牌。
(G) 用户代理将访问令牌传递给客户端。
简化模式参数
参数 | 解释说明 |
---|---|
client_id | 客户端接入标识。 |
response_type | 简化模式固定为token。 |
scope | 客户端权限。 |
redirect_uri | 跳转uri,当授权码申请成功后会跳转到此地址,并在后边带上code参数(授权码)。 |
3, 密码模式(Resource Owner Password Credentials)
因此密码模式一般用于我们自己开发的,第一方原生App或第一方单页面应用。
授权流程
(A)资源拥有者将用户名、密码发送给客户端
(B)客户端拿着资源拥有者的用户名、密码向授权服务器请求令牌(access_token)
(C) 授权服务器将令牌(access_token)
注意:**
发送给client 这种模式十分简单,但是却意味着直接将用户敏感信息泄漏给了client,因此这就说明这种模式只能用于client是 我们自己开发的情况下。
4, 客户端模式(Client Credentials)
客户端模式 client credentials 不支持refresh token 这种是被信任的内部client使用。一般内部平台间使用
授权流程
(A)客户端向授权服务器发送自己的身份信息,并请求令牌(access_token)
(B) 确认客户端身份无误后,将令牌(access_token)发送给client
参数列表如下**:
参数 | 说明 |
---|---|
client_id | 客户端准入标识。 |
client_secret | 客户端秘钥。 |
grant_type | 授权类型,填写client_credentials表示客户端模式 |
可参考文档地址
-
RFC6749:RFC 6749: The OAuth 2.0 Authorization Framework (rfc-editor.org)
-
微博OAuth:Oauth - 微博API (weibo.com)
单点登录
简介:
单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO 并不能算是一种架构,只能说是一个解决方案。SSO核心意义就一句话:==一处登录,处处登录;一处注销,处处注销。==就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,即用户只需要记住一组用户名和密码就可以登录所有有权限的系统。
简图:
应用场景:
单点登录在大型网站使用非常频繁,例如阿里巴巴网站,在网站的背后是成白上千的子系统,用户的一次操作可能涉及到几十个子系统的协作,如果每个子系统都需要用
户验证,不仅用户会疯掉,各系统也会为这种重复授权搞疯。
需要解决的两点:
解决如何产生和存储信任,系统如何验证这个信任的有效性(1.存储信任 2.验证信任)
- 通过页面重定向的方式
通过父应用和子应用来回重定向进行通信实现信息安全传递。父应用提供一个GET方式登录接口,用户通过子应用重定向连接方式访问这个接口。如果用户还没有登录则返回登录页面,
如果用户登录了则生成加密的Token并且重定向到子应用提供验证Token的接口,通过解密校验后,登录当前用户
优点:较Cookie方式安全些
缺点:不方便
-
使用独立登录系统
把授权的逻辑与用户信息的相关逻辑独立成一个应用(用户中心),用户中心不处理业务逻辑,只是处理用户信息的管理以及授权给第三方应用。第三方应用需要登录的时候把请求转发给用户中心 进行处理,处理完毕后返回凭证,第三方验证凭证,通过后就登录用户
多点登录
简介:
传统的多点登录系统中,每个站点都实现了本站专用的帐号数据库和登录模块。各站点的登录状态相互不认可,各站点需要逐一手工登录。
多点登录限制(禁止用户多点在线):
一个端同一个账号只能登录一个实例,例如一个账号在网站端登录后,后一个人使用这个账号在网站端登录,前一个人会被挤下去并会收到通知“你已在别处登录…”
简图:
三方登录(qq登录有道云)
- 有道云url
https://note.youdao.com/
signIn/index.html?&callback=https://note.youdao.com/web&from=web
- 重定向到qq
https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=100255473&response_type=code&redirect_uri=https%3A%2F%2Fnote.youdao.com%2Flogin%2Facc%2Fcallback&state=QSOLTL6LTS0quhLgu0Lwz0ZZZZZZQMqy0
解析:
client_id=100255473
------->利用client_id去获取临时凭证code
response_type=code
------->response_type:授权类型-->code去获取token,
redirect_uri=https%3A%2F%2Fnote.youdao.com%2Flogin%2Facc%2Fcallback
------>使得一个路由地址A与另一个路由地址B联系起来,执行A的时候会跳转执行B。
state=QSOLTL6LTS0quhLgu0Lwz0ZZZZZZQMqy
--->state生成随机算一个字符串,然后保存在当前用户的session,回调时检查state参数 ----->和当前用户session里面的值是否一致.攻击者无法猜对方的state值是多少.就无法拼出用于攻 ----->击的url
------>忽略 state 参数,会导致出现 CSRF 漏洞。
- 流程