OAuth 授权过程工作原理讲解

转自:http://www.imooc.com/article/10931

在一个单位中,可能是存在多个不同的应用,比如学校会有财务的系统会有学生工作的系统,还有图书馆的系统等等,如果每个系统都用独立的账号认证体系,会给用户带来很大困扰,也给管理带来很大不便。所以需要设计一种统一登录的解决方案。比如我登陆了百度账号,进贴吧时发现已经登录了,进糯米发现也自动登录了。常见的有两种情况,一种是SSO(单点登录)效果是一次输入密码多个网站可以识别在线状态;还有一种是多平台登录,效果是可以用一个账号(比如QQ账号)登录多个不同的网站。

SSO与多平台登录

SSO一般用于同一单位的多个站点的登陆状态保持,技术上一般参考CAS协议;多平台登录一般是Oauth体系的协议,有多种认证模式但是不具备会话管理和状态保持。
不过从本质上讲,我觉得两者都是通过可信的第三方进行身份验证,如果说同一单位的多个子系统共同只围绕一个第三方账户(可以称为认证中心)进行多平台登录验证,那么在第三方平台登录后再访问其他网站,效果和统一登录是差不多的。此外,Oauth2还有个好处就是可以实现跨平台的登录管理,因为他的认证过程不依赖于session和cookie,比如对于移动端设备,以及在前后端分离后这种登录认证方式也可以起到很大作用。
这篇文章里我就着结合之前项目中整合过的OAUTH2来讲一讲这种登录认证的过程。项目是基于Shiro+ALTU实现,参考方案mkk/oauth2-shiro - 码云 - 开源中国 。

oauth2的基本概念

在Oauth中至少是有用户,应用服务器,认证服务器这几个角色在交互。OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"应用服务器"进行互动。

OAuth2的基本流程

用户通过浏览器访问一个应用,比如我要上慕课网学习。

  1. 网站要求我登录,我选择使用QQ登录,这里的QQ登录就是那个认证服务器。
  2. 这个时候慕课提供的QQ登录链接会把我带到QQ登录页面
  3. 在QQ的登录页面完成登录后,选择授权,也就是允许慕课网获取我的资料。
  4. 这个时候我们看到浏览器经过几次跳转后返回慕课网,这个时候我们已经完成了登录。

重点在于几次跳转的过程中,慕课网和QQ登录的服务之间还有过几次交互。

  1. 我们选择了授权的时候QQ登录服务器会根据慕课跳转到QQ时候给出的重定向链接返回给慕课网一个code,这个code代表QQ的登录服务器认可慕课网这个应用服务器的这个请求是合法的予以放行.
  2. 慕课这个时候就会用这个code再次向QQ登录服务发起请求服务令牌(token)。
  3. 拿到这个令牌之后,接下来慕课需要用户的一些基本信息时就可以通过在向QQ服务提交的请求头里带上这个令牌,令牌验证通过就可以拿到用户资源。

这一部分的操作是应用服务器和验证服务器之间的交互,这个过程对用户是透明的。这个过程中慕课网是不需要知道用户的账号密码也可以完成对用户身份的认证,这个token就可以用来标识用户资源。
官方的运行流程图是这样的:

OAuth的几种认证模式

上述讲的是OAuth2中支持的授权码(CODE)方式的认证流程,也是其支持的四种认证方式里最复杂的,其他的三种种包括:

  1. 简化模式(implicit),(在redirect_uri 的Hash传递token; Auth客户端运行在浏览器中,如JS,Flash)
  2. 密码模式(resource owner password credentials),将用户名,密码传过去,直接获取token;
  3. 客户端模式(client credentials),无用户,用户向客户端注册,然后客户端以自己的名义向'服务端'获取资源;
    详细的OAuth2资料参考理解OAuth 2.0|阮一峰的网络日志
    分别适用不同场景,复杂度也比授权码模式要低,所以这里就只说说授权码模式的具体过程。

CODE方式认证实例

假设现在有一个应用服务器跑在我本机8000端口,认证服务器在8090端口。在需要用户登录时候把用户带到以下的一个URL.

http://localhost:8090/oauth/authorize?response_type=code&scope=read write&client_id=test&redirect_uri=http://localhost:8000/login&state=09876999

我们注意到几个重要的参数:

  • response_type:表示授权类型,就是上面讲的那四种类型,这里用的是code方式。
  • client_id:表示客户端的ID,代表哪个应用请求验证
  • redirect_uri:表示重定向URI,验证以后的回调地址,一般用来接收返回的code,以及做下一步处理。
  • scope:表示申请的权限范围,
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。作为安全校验。

如果以上步骤都通过的话,认证服务器会转向这个会调地址,带上发放的Code码,类似如下:

http://localhost:8000/login?code=bca654ab6133ab3cbc55bb751da93b1c&state=09876999

可以看到带回了返回的参数,以及原样返回的状态码。

应用服务器这时候拿到返回的code去换token,发起如下的一个请求:

http://localhost:8090/oauth/token?client_id=test&client_secret=test&grant_type=authorization_code&code=bca654ab6133ab3cbc55bb751da93b1c&redirect_uri=http://localhost:8000/login&scope=read%20write&state=09876999
与之前请求类似只是多了一个code字段,去验证客户端的合法性。


验证服务器会在收到code以后去查找是否有支持这种code的处理器,如果有则发放token。



原文地址:https://www.cnblogs.com/520playboy/p/7282652.html