前言
之前都是基于SpringSecurity开发的基于表单的认证,我们现在需要开发基于第三方授权登录认证,常见的是QQ和微信登录等。常见第三方登录使用SpringSocial框架。
Spring Social和Spring Security OAuth都是基于OAuth协议提供功能的,所以需要我们对OAuth协议有一个全面了解。
主要说明以下三点:
- OAuth协议要解决的问题
- OAuth协议中的各种角色
- OAuth协议运行流程
内容
1. OAuth协议要解决的问题
我们在现实中开发一个app功能,用于读取微信里面的图片或者视频,然后对这些图片或者视频进行读取并美化。对微信而言会增加用户粘合度,对于app而言,不用自己去维护用户,效率会很高。
最大的问题是微信不会允许app随便读取维护客户信息,那么这个时候就需要用户的一个授权,用户同意我去动用户微信里面的图片和视频。如何得到用户授权呢?传统做法是我跟用户去要用户名/密码;一方面用户不愿意给,另一方面用户就算给了,app端读取用户信息存在很大问题。
- 应用可以访问用户在微信上的所有数据
- 用户只有修改密码,才能收回授权
- 密码泄露可能性可能大大提高(如果有多个应用都采用用户名/密码模式,那么只要有一个应用泄露了用户名/密码,那么此密码就会被泄露)
OAuth协议就是为了解决以上问题而诞生的,他的主要意义:
1.用户不用把其用户名/密码告诉我,而是只需要通过一个令牌(Token);我们再去访问 微信信息时候就会携带这个令牌而不是用户名/密码,那么之前存在的3个问题都不存在了。 (1):首先令牌上写着:授权信息是你只能访问用户的自拍数据 (2): 令牌上有一个日期,当过了这个日期后你将不再有权限访问用户信息,回收授权不用修改密码。
(3): 因为我们没有把用户密码给app应用,而是给了一个令牌,所以不会存在用户密码泄露问题。
2. OAuth协议中的各种角色(5个角色)
首先介绍OAuth协议存在的角色,
- 服务提供商(Provider):提供Token令牌,以上对应微信
- 资源所有者(Resource Owner):资源指代用户的自拍数据:图片,视频;自拍数据真正所有者是用户而不是微信,用户只是把这些数据放到了微信上,真正拥有人是用户。
- Client(第三方应用):把微信用户变成自己用户,属于第三者,叫做第三方应用。
在用户提供商:Provider之上又存在以下角色:
- 认证服务器(Authorization Server):a.验证用户身份,b.产生令牌。
- 资源服务器(Resource Server):a.保存用户的资源数据,b.验证令牌
逻辑上认证服务器和资源服务器是两个角色,但是真正物理上,他们可以是一台机器。
3. OAuth协议运行流程
用户访问第三方应用,应用请求用户授权,用户决定同意或者不同意,同意授权,那么第三方应用会去访问服务提供商的认证服务器,然后告诉他用户同意获取用户信息,叫服务提供商返回一个token令牌,在返回token前认证服务器会校验应用是不是说的假话,如果确实同意了,那么认证服务器会发送一个令牌给第三方应用。第三方应用拿到这个令牌token之后,会携带token去资源服务器申请资源,资源服务器会校验第三方携带的令牌,确认校验无误他会同意用户资源让第三方应用访问。
上面7个步骤,除了0.打开客户端不包括在用户流程里面,这6个步骤里面2.同意授权是关键.针对于2.同意授权----有4种方式去实现。
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
授权码模式和密码模式是需要了解的重难点,简化模式和客户端模式不介绍,用的比价少。
授权码模式是使用最严谨,应用最广泛的模式,现在国内大部分大厂都是基于授权码模式。
4. 授权码模式流程
用户访问第三方应用客户端client,第三方应用Client将用户导向认证服务器,用户同意授权后,服务提供商导回Client(第三方应用)并携带授权码(导向到第三方应用的哪个url地址上,是第三方应用和认证服务器之间协商的,将用户导向到第三方应用特定的url时候,返回的是授权码而不是令牌token)。 第三方应用收取到这个授权码之后,携带授权码申请令牌,认证服务器会校验第三方应用携带的授权码,确认无误后发送令牌。
以上是授权码模式的一个过程,为什么叫做授权码模式,是因为:这个过程中会产生一个授权码,在其他模式中是没有授权码的所以叫做授权码模式。
这个模式有2个主要特点:
- 用户同意授权的动作实在认证服务器上进行的,而其他授权模式里面,密码/客户端模式都是在客户端第三方应用上完成的。完成了以后,第三方应用携带这些信息向认证服务器申请令牌指明用户授权给我了。这个时候,认证服务器是没法 确定用户是不是真的授权了,有可能用户授权需要的信息是第三方自己伪造的。而授权码模式里面统一授权是在认证服务器上进行的。所以认证服务器知道,用户确实同意了授权。
- 在用户同意授权时候,服务提供商给第三方应用返回信息不是最终的令牌,而是一个授权码,第三方应用接受到这个授权码之后,要从第三方服务器发送请求给认证服务器,拿着这个授权码去换认证令牌。这种情况下 必须要求第三方应用有一个服务器,那么像有些网站可能就是一个静态网站,只有一些页面没有服务器,那么这种网站就会使用四种模式中的第二种模式:简化模式。在简化模式里面从第三方应用请求认证服务器时候,直接带的就是令牌。只能返回到页面上,用脚本读取放回令牌,所以在浏览器里面就能获取到令牌。所以授权码模式比简化模式安全。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。