写在前面:
在正式介绍OAuth2.0之前我们先来看一个场景:小李是一个文艺小青年, 经常喜欢出去旅游并且把自己旅行中的美景照片分享到各大社交网站上,比如朋友圈,新浪微博。小李马上要向女朋友求婚了,他想把这三年来和自己女朋友出去旅游的照片打印出来做成照片墙,好在求婚的时候讲女友感动的一塌糊涂,然后你懂得...,那么问题来了,按照小李带女朋友一个月出去玩一次,每次分享30张照片,三年就是30 * 12 * 3 = 1080 张,小李现在想把这1080张照片全部打印出来他首先得找个提供打印照片服务的公司(美图快印),然后把需要打印的照片给到服务公司然后才能打印。怎么把这些照片给到美图快印呢,一般来说有下面两种方式:
1.小李到自己的微博相册中吭哧吭哧下载他需要打印的所有照片,然后装到U盘里或者转储到网盘里,再给到美图快印(那可是1080张照片啊,纯手工操作,好累啊)
2.小李到美图快印告诉工作人员自己的账户名和密码,并告诉他那些需要打印,那些不需要打印,然后小李还会担心:自己和女友的亲密照被工作人员看到了怎么办(更可怕的是某一天自己会不会出现在某论坛上成为网红)?万一他记住了我的密码然后悄悄的登陆上去把我的密码改了怎么办?。。。。
小李觉得有点头疼了,有没有什么方法客户既不告诉工作人员自己的账号和密码又能够方便快捷的把照片给到美图快印呢?
这就要说到我们今天的正题了,用OAuth就可以轻松的解决此类特定范围的授权问题。
OAuth2.0简介:
OAuth2.0 是一个开放的工业标准的授权协议,它允许用户授权让第三方应用直接访问用户在某一个服务中的特定资源,但是不提供给第三方账号及密码信息。完整定义请移步官网:https://oauth.net/2/
OAuth2.0的基本概念
在了解OAuth2.0之前我们有必要先介绍一下下面几个基本的概念:
1. 资源所有者(Resource Owner):一个能够访问受保护资源的实体。当资源所有者是一个人时,它被称为终端用户。(小李)
2. 资源服务器(Resource Server):托管受保护资源的服务器,能够使用访问令牌接受和响应受保护的资源请求。(新浪微博)
3. 客户端(Client):代表资源所有者和其授权的应用程序来保护资源请求。术语客户端并不意味着任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行)(美图快印)
4. 授权服务器(Authorization Server):在成功验证资源所有者并获得授权之后,服务器向客户端发出访问令牌。(授权服务器是用来管理Resource Owner,Resource Server,Client的中间人)
Authorization Server和Resource Server可以使独立的服务提供商,也可以是在一起的,比如上面例子中新浪微博既作授权服务器也用来存储用户的图片资源,OAuth2解决的问题是:通过Authorization Server可以提供一个访问的凭据(token)给client(美图快印的工作人员),使得client可以在不知道Resource Owner以及Resource Server的用户名和密码的情况下访问到Resource Owner受保护的资源,它是一个完美的中间人。
OAuth2.0详解
通常 Resource server本身就提供Authorization server服务,它主要提供两类接口:
- 授权服务接口:接受Client的授权请求,并引导用户到Resource server完成登陆授权的过程。
- 获取访问令牌的接口:使用授权接口提供的许可凭据来颁发Resource owner的访问令牌给Client,或由Client更新过期的访问令牌。
除此之外还需要提供一个第三方应用程序注册管理的服务。通常情况下会为注册完成的第三方应用程序分配两个成对出现的重要参数:
- client_id:第三方应用程序的一个标识id,这个信息通常是公开的信息,用来区分哪一个第三方应用程序。
- client_secret:第三方应用程序的私钥信息,这个信息是私密的信息,不允许在OAuth2流程中传递的,用于安全方面的检测和加密。
Client在取得client_id和client_secret之后再向Authorization Server发起授权请求,并获取AccessToken,然后携带Token来访问和消费受保护的资源。美图快印要想直接获取小李新浪微博相册中的照片资源就需要先引导小李到新浪的登陆界面,然后完成授权登陆,然后再向授权服务器发起授权请求,然后获取到新浪微博办法给他的token,再携带者token才能访问到微博的相册。
下面我们来看一下OAuth2.0的详细授权过程:
我们可以看到在上述的授权过程中最关键的部分是获取token的那一步,这也是OAuth2.0的核心。有了这个token我们就可以访问到resource server上的资源,ABCD这几步都是为了获取这个token。
那么这个token到底包含了哪些信息呢?我们来从头分析一下,我们需要实现的是:让美图快印能够在不用小李用户名和密码的前提下访问到小李新浪微博账户相册中的特定图片。
注意上面加粗的部分,要实现这样的需求我们需要从token中解析出来下面3类信息:
- 客户端标识,表明是谁在请求访问资源(美图快印);
- 用户标识,得到了谁的许可(小李);
- 客户端能访问资源所有者的哪些资源以及其相应的权限。
有了上面的这些信息,那么资源服务器(Resouce Server)就可以区分出来是哪个第三方应用(Client)要访问哪个用户(Resource Owner)的哪些资源(以及有没有权限)
在上面的流程中出现了授权许可(Authorization Grant)这个概念,那到底它是什么意思呢?
书面解释是:授权许可是一个代表资源所有者授权(访问受保护资源)的凭据,客户端用它来获取访问令牌。
这个解释比较抽象,那么我们来翻译一下就是:授权许可是小李授予美图快印获得新浪微博相册的访问令牌的一个凭据。
那么我们该如何获得这个凭据呐,OAuth2定义了四种许可类型:
- Authorization Code:授权码;
- Implicit:隐式许可;
- Resource Owner Password Credentials:资源所有者密码凭据;
- Client Credentials :客户端凭据。
具体每一种许可类型到底怎么实现我们将放到后面详细讨论,本文不做详细解释。
写到最后:
总结:OAuth2.0是一套工业级的标准授权协议,可以很方便的解决第三方服务的授权而不需要资源所有者直接提供身份信息,它大大降低了我们在实现认证和授权时的复杂度。目前基于OAuth2.0实现的框架有很多,基于.NET Core实现最好的是IdentityServer4
在后续文章中我们将一起探讨IdentityServer4在.NET Core中的使用,欢迎持续关注。
参考资料: