jwt、oauth2和oidc等认证授权技术的理解
前言
jwt、oauth2、oidc等,都是和认证授权相关的规范或者解决方案,因此要理解他们,就需要从业务场景的适用性一步步的分析和认识。
一、认证授权业务场景理解
就个人目前的理解来看,一个好的软件系统的构成可能需要包含但不限于以下几个方面:
功能
性能
拓展
安全
不论是从公司或者项目角度而言,还是从个人开发者的角度而言,有相当大一部分可能都只在功能部分停留。
何谓功能,我的理解就是实现业务需求里的要求,满足需求文档需要的效果,流程走通、可交付使用。因此这里说的功能,和仅仅是流程走通还是有一定区别的。
在功能的基础上,有的客户可能在需求里就对一些性能有要求,或者有些公司的项目团队有一定追求,那么可能就更进一步,会在功能的基础上再注重性能。
那么这里的性能就会涉及到整个架构的设计、技术的选型以及代码的规范和调优。
至于拓展性,实际上和上边一条就有些类似了,不论是动机还是处理方式都差不多。
只不过在分布式、微服务和容器盛行的今天,很多项目的第一选择就是这两个,那么在架构层面来说,其实一开始就具备了一定的拓展性。
而说到安全,很多人第一时间想到的可能是用户名密码这些,这也是最常见到的安全里的内容。
但是实际上软件的安全远远不止用户名密码的管理和校验,还包含数据传输的安全、资源权限的安全等。
而标题所说的认证授权,也正是安全范畴里的内容,更确切的说,应该是资源权限控制的范畴。
二、token的理解
token这个词,很多做开发的应该都知道,比较常见的就是在用户名密码登陆后,后台生成一个token,然后客户端保存token。
客户端只有获取了正确的token后,在发起业务请求时携带这个token,才能正常进行后续的业务处理。
那么这个token既然是为了保证安全、用来校验用户是否登录的,token本身的安全自然也是需要注意的,所以一般的token就有了签名加密的处理。
而至于token里的内容定义以及格式定义,理论上讲只需要客户端和服务端协商一致即可。
但是考虑到token的通用性和广泛性,因此慢慢的就有了一些token定义的规范,一个目前比较通用的token规范就是jwt。
三、jwt的理解
jwt是json web token的简称,标准的jwt格式token包含了三段,分别是token头、token主题和token签名,三部分以点符号分割。
jwt作为一种规范,也可以说一种解决方案,本身就可以拿出来做很多的解读,更多jwt的知识可以参考阮一峰的博客:
http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
对于认证授权来说,只需要先了解到这个jwt是一种通用规范和格式的数据,安全、通用就好。
jwt是一种token规范,那么在用户登录的时候,就可以生成这种规范的token,这样在后续解码、签名验签、数据处理等需求上就可以减少很多的沟通成本。
但是jwt只是处理token规范的问题,却不处理其他token规范之外业务的问题,比如token如何能方便刷新的问题,比如究竟是简单地登录业务,还是涉及到第三方服务的授权业务,还是带有授权和认证的业务等等。
而这个问题,就引申出了oauth2。
四、认证和授权的理解
要想弄清oauth2,实际上必须先弄清认证和授权这两个概念。
从英语单词来看,认证和授权其实非常的像,分别是 authentication 和 authorization,在实际开发中,很多人也不太能分清楚。
即使是我自己,虽然近段时间有一定的理解,却不敢保证就是对的,只能说现阶段我觉得是这样。
我理解的认证,从字面意思说,就是身份的认证;而授权,则是资源的授权。
借用网络上别人写的:认证解决的是你是谁,而授权解决的是可以给你什么。
那么从这个角度来说,一个常规的登录获取token,之后在其他业务中校验token,其实只能算是认证的一个范畴,因为这个token的作用只是校验访问者的身份以及是否检验过这个身份,只要身份验证通过,所有资源都可以用。
假如在服务端的接口中涉及到了不同的权限问题,然后能够从token中获取到这些权限,并根据这些权限确定是否要处理该请求的资源,那么这里才算是真的涉及到了授权。
需要注意的是,这里的权限是资源的权限,而不是用户的角色权限这些,这是两个概念。
更多认证授权的理解,也可以参考其他的博客,例如:
https://www.cnblogs.com/jinhengyu/p/10257792.html
五、oauth2的理解
和jwt一样,oauth2也是一种规范,因为规范,就逐渐的形成了一些特定的解决方案,例如spring的oauth2。在认证和授权的业务中,oauth2解决的就是授权规范的问题。
在业务交互的过程中,oauth2授权直观的提现,也是通过token。
标准的oauth2的token同样是遵循jwt标准,不同的是,在普通jwt的token基础上加入了更多的内容。
oauth2标准的token有两个:access_token和refresh_token。
access_token用来访问资源时授权,包含基础授权信息,refresh_token的作用是在access_token失效后直接续签access_token,即上边说的如何方便刷新和续签token的问题。
同时,oauth2中的授权分为客户端模式、授权模式、简化模式、密码模式四种,可以根据不同的业务场景。
和上边用户名密码登陆不同的是,oauth2中解决的更多是涉及到第三方服务的业务。
对于oauth2的详细理解和四种授权模式,可以参考后边链接中的内容,不过有些地方可能需要参考更多其他博客,不见得都对。
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
六、oidc
大多数系统,实际上用到oauth2就已经足够了,因为即使说服务涉及到了第三方,但是大多数时候这些第三方资源可能都是公司内,或者一个大的团队内。
但是随着互联网的发展,越来越多的系统或应用会集成外部的第三方,例如支付宝等第三方支付、例如QQ等第三方登录。
因此,openid这个技术和规范就应运而生,这个技术解决的就是外部第三方交互时的一个身份认证问题。
结合上边所说,认证和授权分别属于不同的范畴,解决的也都是不同的问题,因此在这种涉及到第三方,如果再涉及到资源权限的系统中,就会引入一个新的规范,即oidc。
OIDC=(Identity, Authentication) + oauth2,我的理解就是openid+oauth2。
具体的用法和实现上就是,OIDC在oauth2的基础上又加了一个token,叫做id_token。
id_token同样的遵循jwt规范,只不过里边的内容是能够体现用户身份的信息。
因此,OIDC里就会有三个token:access_token、refresh_token和id_token。
对于实际使用来说,理解到这里应该就差不多能够明白为什么的有的应用会一次返回三个token,不知道究竟该使用那个了。
若想了解OIDC更多的内容,可以参考下边的博客:
https://www.cnblogs.com/linianhui/p/openid-connect-extension.html