首先,设想一种情境:你平常会使用一款照片存储App(以下照片服务指代),用来将自己喜欢的照片存放在上面以备随时查看。假如有一天,你想要打印其中的某张照片而且你找到了一款打印照片App(以下打印服务指代)。此时你应该怎么将照片给到打印App呢?其实这就涉及到了授权的问题,你必须让照片服务授权打印服务访问指定的照片。
也许,最直接的方式就是把用户和密码给到打印服务,这样的话打印服务就可以代替你直接去登录照片服务拿到任意的照片。但是这种方式很明显有极大的安全风险,因为你不能保证打印服务不会访问你的其他照片并且去做坏事。因此在这种背景下,OAuth2协议应运而生。本文就围绕Oauth2为主题,解析它的具体定义以及各种模式,更重要的是不同模式的使用场景。
在具体讲解Oauth2的定义之前,有几个概念有必要先了解一下:
照片存储App在上面的情境中就可以看做是资源服务器打印照片App就是一种客户端(单页应用、无线应用等也属于客户端)本节具体讲解Oauth2四种不同的授权模式,分别是:授权码模式、隐含模式、密码模式、客户端凭证模式,以及它们不同的使用场景。
授权码模式是Oauth2协议里最安全的一种模式(微信、微博第三方登录都是基于该模式),如果上面照片服务和打印服务隶属于不同公司,并且打印服务有自己的服务器。那么在这种情景下,必须要用授权码模式保证资源的安全,它的主要流程是:
code,请求的格式如下:http://localhost:8080/oauth/authorize?
client_id=testClient&redirect_uri=http://localhost:8080/callback&response_type=code&scope=read_userInfo&state=x1f2xs
token,请求格式如下:curl -X POST --user testClient:testSecret http://localhost:8080/oauth/token
-H ‘content-type:application/x-www-form-urlencoded‘
-d "code=QvjUaf&grant_type=authorization_code&redirect_uri=http://localhost:8080/callback&scope=read_userInfo"
token后,客户端就可以请求指定的api进行资源访问,请求格式如下:curl -X GET http://localhost:8080/api/xxx -H ‘Authorization:Bearer LIYcLu400YNX5CzJpZ39XG7J9kw‘
授权码模式主要涉及到
code和token的获取,只有获取到token后才有权限访问资源。code是通过前端的方式传递的,但是就算code被截获,由于token是在服务器中完成请求的,一般clientSecret是不会泄露的,并且获取token还需state验证(state会和会话进行绑定),因此token泄露的风险极小,所以推荐使用这种模式来颁发token。
打印服务是个spa应用,那么授权码模式很显然并不适用,因此Oauth2还提供了隐含模式来处理这种情况。它的主要流程如下:
token,请求格式如下:http://localhost:8080/oauth/authorize
?client_id=testClient&redirect_uri=http://localhost:8080/callback&response_type=token&scope=read_userInfo
需要注意的是这种模式并不是一种十分安全的模式,因为token有被泄漏的风险。因此除非是像上述这种必要的场景,一般不适用这种模式,并且在这种模式下token的失效时间需要尽可能的短。
token后请求资源服务器curl -X GET http://localhost:8080/api/xxx -H ‘Authorization:Bearer LIYcLu400YNX5CzJpZ39XG7J9kw‘
照片服务和打印服务同属一个公司,那么可能不需要很严格的安全防范。因此Oauth2还提供了密码模式来颁发token`,主要流程如下:
token接口,请求格式如下:curl -X POST --user testClient:testSecret http://localhost:8080/oauth/token
-H ‘content-type:application/x-www-form-urlencoded‘
-d ‘grant_type=password&username=joe&password=123&scope=read_userInfo‘
这种模式严格来说是很不安全的,因为你把用户名和密码给了客户端,然后代替你去登录网站。默认也不推荐使用这种模式,除非是特别信任的系统或者是同一组织的产品。
token后请求资源服务器curl -X GET http://localhost:8080/api/user/info -H ‘Authorization:Bearer LIYcLu400YNX5CzJpZ39XG7J9kw‘
客户端凭证的方式来颁发token,主要流程如下:
tokencurl -X POST --user testClient:testSecret http://localhost:8080/oauth/token
-H ‘content-type:application/x-www-form-urlencoded‘
-d ‘grant_type=client_credentials&scope=read_userInfo‘
这种方式更加地简单,只需要向授权服务器申请过凭证,就可以访问资源,一般用于纯及机器之间的交互。
token后请求资源服务器curl -X GET http://localhost:8080/api/user/info -H ‘Authorization:Bearer LIYcLu400YNX5CzJpZ39XG7J9kw‘
至此,关于oauth2协议的四种模式已经讲解完了,并且针对它们不同的使用场景也做了阐述。Oauth2协议在微服务系统盛行的今天有着很重要的作用,往往会在网关层担当权限控制的角色。并且Oauth2只是定义了协议,并不是具体的实现,像Spring Security Oauth2、Google OAuth Java Client等都对它有比较好的支持,具体的使用可以借助这些框架来展开。
原文:https://www.cnblogs.com/joebig7/p/14607210.html