很多网站、APP 没有搭建自己的账号体系,而是直接微信,QQ,微博的这种授权方式登录。
如果需要用户名密码登录网址,app 需要明文保存用户的微博账号和密码,这样很不安全。
一旦网站、APP,被攻击就会导致用户密码泄漏,以及所有使用微信,QQ,微博登录的网站的数据泄漏。
为了解决以上的问题,OAuth 协议应运而生。
2、定义
Oauth是一个授权机制,目的让一个第三方的应用获取到一个http请求的权限,并授予部分资源访问权限。
3、基本原理
Oauth协议提供了4个部分分别是:
1.Resource Owner(资源拥有者:用户) 2.Client (第三方接入平台:请求者) 3.Resource Server (服务器资源:数据中心) 4.Authorization Server (认证服务器)
当client发起请求到资源服务器后,资源服务器会client的ID和redirect_uri提交给资源拥有者同时进行授权。
资源拥有者收到请求后会校验client的ID是否合法,合法就返回一个授权的页面给client.
client点击确认授权后,资源拥有者就会调用授权服务同时生成一个code码。回调给client
client有了code码后就可以用code码去资源拥有者的授权服务中换取token.拿到token后就拿到了用户ID
下面以processOn登录为例,其实我们在登录processOn的时候可以不需要注册账号密码,因为下面提供了我们qq,google, weibo的第三方登录方式。
step4:
资源服务器拿到这个code后,就可以用code去和微博服务器交换token,拿到token后就得到了uid, 得到uid后再获取用户头像,名称就很容易了,直接call微博服务器就可以了。
OAuth2.0是一个授权框架,他规定了客户从授权服务器获取令牌Token的规则。
要理解OAuth2.0,先要知道为什么会有这个东西产生,或者说他能帮我们解决什么问题,其实简单说他就是帮我们解决了访问安全问题。先看如下的一张图:
图片显示了我们没有引入任何安全机制情况下的资源访问过程,可以看到正常的用户和恶意的用户都可以通过向资源服务器的接口发送请求获得用户数据。显然恶意用户不该获取数据,他是非法获得,这个情况不应该被允许,需要一种机制保护用户数据。
OAuth2.0包含了资源拥有者,授权服务器,客户应用,授权服务器,资源服务器。
客户应用: 通常是一个 WebWeb 或者无线应用,它需要访问用户的。
资源服务器: 是一个 webweb 站点 或者 web service web service web service web service API ,用户的受保护。
授权服务器: 在客户应用成功认证并获得授权之后,向客户应用颁发访问令牌Access Token。
资源拥有者: 资源的拥有人,想要分享某些资源给第三方应用。
1)授权码(Authorization Code Token),仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌
2)刷新令牌(Refresh Token),用于去授权服务器获取一个新的访问令牌
3)访问令牌(Access Token),这是OAuth令牌类型中最核心的一个,用于代表一个用户或服务直接去访问受保护的资源
4)Bearer Token,不管谁拿到Token都可以访问资源,像现钞
5)Proof of Possession(PoP) Token,可以校验client是否对Token有明确的拥有权
上面提到了需要提供一种机制来保护数据,OAuth2.0提供的就是一种授权机制,就是说用户要访问资源必须先通过授权服务器授权拿到Access Token(访问授权),他拿着这个Access Token才能去资源服务器去要他想要的数据,示意图如下:
这里看到我们引入了一个授权服务器,这个授权服务器就是专门负责颁发Access Token的,客户应用需要从授权服务器中获得Access Token,获得后再向资源服务器去获取数据,请求中包含了Token一起发到资源服务器,资源服务器首先要验证这个Token是否合法,如果合法再返回数据给客户应用。
上图中红色圈圈圈起来的就是OAuth2.0框架协议工作的地方,他规定了客户应用如何获取Access Token,以及如何使用Token的整个过程。
其中核心的授权服务器包括了授权端点,令牌端点,校验端点,注销端点,如下图所示:
OAuth2.0中规定了多种授权模式,各种模式实现的复杂程度和安全系数不一样,我们先分别看一下四种授权模式:
1)授权码(Authrization Code)模式:
基本流程是先通过前端渠道客户获取授权码,然后通过后端渠道,客户使用Authrization Code去交换Access Token和可选的Refresh Token,这种模式是最安全的模式,因为令牌不会通过user-agent去传递,完整的过程如下图:
授权码模式的优点是比较安全,他可以有token过期时间,而且上面的第四和第五步都是在服务器之间的访问,很难被截获,用户信息也存在服务端,这样就保证了他的安全性。他的缺点是需要进行多次请求才能访问到资源。
授权码模式假定资源拥有者和客户不在一台设备上,他拥有高安全性的保障,目前市面上主流的第三方认证都是采用这种模式。
2)隐式/简化(Implicit)模式
基本流程是Access Token直接通过前端渠道从授权服务器返回,完整的过程如下图:
3)密码(Resource Owner Password)模式
基本流程是使用用户名/密码作为授权方式从授权服务器上获取Access Token,而且一般不支持refresh token,完整的过程如下图:
4)客户端(Client)模式
基本流程是通过后端渠道去获取一个Access Token,因为客户凭证可以使用对称或者非对称加密,该方式支持共享密码和证书,完整的过程如下图:
客户端模式适合用作服务器间通信场景。
授权码模式有一个基本的选择流程,如下图:
在上一篇文章中,我们已经实现了授权服务器,拿到访问token已经不是问题了。本文主要讲述如何搭建一个资源服务器,根据第三方客户端访问请求和token来实现资源的权限控制。
资源服务器的核心配置类就是需要继承 ResourceServerConfigurerAdapter ,并重写其中的资源配置方法和安全鉴权方法。
token校验有两种方式:
我们该案例中资源服务器和授权服务器是不同的机器,大多数实际业务场景中也是不同的,所以我们以 RemoteTokenServices 为例进行演示,这里放到和资源服务器配置类一块:
资源服务器也是一个独立的应用,所以也需要增加安全访问的配置,这个在先前讲Spring Security的时候已经详细介绍过了。
最后,增加我们的访问资源即可,这里就是Controller。
此时,我们就完成了资源服务器的所有内容。
我们以 客户端模式 启动上一节的授权服务器后,通过HTTP工具(我这里使用IDEA的插件RestClient)来进行如下的测试:
首先访问如下请求以获取访问token:
得到的内容如下:
此时我们先不使用资源服务器,我们使用如下的请求来模拟资源服务器的验证token,以此来判断授权服务器是否能正常工作:
得到的返回内容是:
可以看到,允许访问的资源ID是 user 、访问的资源域是 all ,拥有的权限是 user:query ,供client_id为 iSchool 的第三方应用访问,这和我们前面配置授权服务器时的内容一致,因此授权服务是正常的。
然后,我们就启动资源服务器,现在来请求资源服务器的资源,并带上我们从授权服务器那里得到的token:
得到的返回结果为:
但是,如果我们访问另外一个接口:
得到的结果就是:
很明显,当资源服务请求授权服务的时候,授权服务告诉资源服务,当前这个访问token只有 user:query 权限,所以需要其它权限才能访问的资源就被禁止。
如果我们的资源服务器域名称不是 all ,而是改成了 user ,那么访问资源就会报错如下信息:
在实际的使用场景中,一个访问token并不仅仅限制只能访问拥有权限范围内的接口,还会限制只能访问某个客户的信息,因此我们还需要在授权中增加用户的身份信息。待研究。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)