密码模式,认证服务器是自己内部的服务器.密码模式可以做企业内部的单点登录,微服务的安全校验.
适用的业务场景 客户端应用(手机app) 是高度受信用的,一般是自己公司开发的app项目。
比如说公司有 订单服务 商品服务 会员服务 等等,你要是想访问这些服务就需要认证,你不可能每一个服务都自己去实现一套授权认证系统, 这样一来就把所有的服务的认证功能都独立出一个认证服务出来.
我们请求过来了之后可以先去认证服务进行一个认证,如果认证完了拿到一个access_token之后,会带着access_token去访问各个目标微服务,各个目标微服务直接去校验access_token是否合法,有没有失效即可, 当然各个目标微服务校验逻辑可以直接上升到网关层去做校验.
请求过来之后,先去进行登录,获取一个token,然后去访问其它微服务的时候之前在网关的过滤器里面去访问授权服务校验token是否有效的,如果是有效的就可以继续访问下游的微服务,如果是无效的话,就直接就请求打回去了
授权码模式(最安全的模式) 业务场景 第三方不授信的,搭建自己的开发能力平台。
它的步骤如下:
(A)用户访问客户端,后者将前者导向授权服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向授权服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
> https://b.com/oauth/authorize?> response_type=code& #要求返回授权码(code)> client_id=CLIENT_ID& #让 B 知道是谁在请求 > redirect_uri=CALLBACK_URL& #B 接受或拒绝请求后的跳转网址 > scope=read # 要求的授权范围(这里是只读)>
客户端申请授权的URI,包含以下参数:
response_type:表示授权类型,必选项,此处的值固定为"code"client_id:表示客户端的ID,必选项redirect_uri:表示重定向URI,可选项scope:表示申请的权限范围,可选项state:表示客户端的当前状态,可以指定任意值,授权服务器会原封不动地返回这个值。 用户跳转后,B 网站会要求用户登录,然后询问是否同意给予 A 网站授权。用户表示同意,这时 B 网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面这样。
> https://a.com/callback?code=AUTHORIZATION_CODE #code参数就是授权码>
A 网站拿到授权码以后,就可以在后端,向 B 网站请求令牌。 用户不可见,服务端行为> https://b.com/oauth/token?> client_id=CLIENT_ID&> client_secret=CLIENT_SECRET& # client_id和client_secret用来让 B 确认 A 的身份,client_secret参数是保密的,因此只能在后端发请求> grant_type=authorization_code& # 采用的授权方式是授权码> code=AUTHORIZATION_CODE& # 上一步拿到的授权码> redirect_uri=CALLBACK_URL# 令牌颁发后的回调网址>
B 网站收到请求以后,就会颁发令牌。具体做法是向redirect_uri指定的网址,发送一段 JSON 数据。
> { > "access_token":"ACCESS_TOKEN", # 令牌> "token_type":"bearer",> "expires_in":2592000,> "refresh_token":"REFRESH_TOKEN",> "scope":"read",> "uid":100101,> "info":{...}> }
简化模式(开发几乎不用) 开发中几乎接触不到 适用于 客户端就是一堆js css html 没有前端服务器
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌,这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)
简化模式不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这个步骤,所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
开发中几乎用不到,这种模式 用户都没有参与过程