微服务安全(二)OAuth 2.0
1. 概念
OAuth是一个开放的、安全的用户认证协议,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源,而无须将用户名和登录口令提供给第三方应用。授权的第三方应用只能在特定的时段内访问特定的资源,而非所有内容。每次授权的令牌只能针对一个第三方应用,因此可以认为OAuth是一个非常安全的用户认证/授权协议。
2010年4月OAuth发布了2.0版本,并在2012年10月正式发布为RFC6749。OAuth 2.0对认证流程进行了简化,更加关注客户端开发者的简易性,并为Web应用、桌面应用、手机App等提供专门的认证流程。但OAuth 2.0并不向下兼容OAuth 1.0。基于OAuth 2.0的用户认证具有以下优点。
- 简单:不管是OAuth 2.0服务的提供商还是应用开发商,都易于理解与使用;
- 安全:用户认证过程中并不涉及用户密钥等信息,使认证方案更安全、更灵活;
- 开放:OAuth 2.0只是一个用户认证安全协议,所以任何服务提供商都可以基于该协议来实现,任何软件开发商都可以使用该协议完成用户认证流程
2. 流程
OAuth 2.0的授权流程如下图所示:
具体步骤如下:
- 用户打开客户端以后,客户端要求用户给予授权;
- 用户同意给予客户端授权;
- 客户端使用上一步获得的授权,向认证服务器申请令牌;
- 认证服务器对客户端进行认证以,确认无误后同意发放令牌;
- 客户端使用令牌,向资源服务器申请获取资源;
- 资源服务器确认令牌无误,同意向客户端开放资源
从OAuth 2.0的授权流程中可以看到基于OAuth 2.0的授权涉及下面4种角色:
- 资源拥有者:资源拥有者是对资源具有授权能力的人,通常也就是我们所说的用户;
- 客户端/第三方应用:客户端/第三方应用代表资源所有者对资源服务器发出访问受保护资源的请求;
- 资源服务器:资源所在的服务器,也就是受安全认证保护的资源;
- 授权服务器:就是通常所说的认证服务器,为客户端应用程序提供不同的访问令牌。授权服务器可以和资源服务器在统一服务器上,也可以独立部署
3. 客户端授权模式
从前面的授权流程中可以看到,客户端必须得到用户的授权,才能从授权服务器中获得访问令牌。在OAuth 2.0中定义了4种客户端授权模式,其中主要用到的三种分别是授权码模式(Authorization Code)、简化模式(Implicit)以及密码模式(Resource OwnerPassword Credentials)。
3.1 授权码模式
授权码模式是OAuth 2.0中功能最完整、流程最严密的授权模式。授权流程如下图所示:
具体步骤如下:
- 用户访问客户端,客户端将用户引导到授权服务器上;
- 用户选择是否同意给客户端授权;
- 如用户同意授权,授权服务器将重定向到客户端事先指定的地址,同时附加上一个授权码(Token);
- 客户端收到授权码后,同时附加上需要重定向的页面(如果有的话),经由客户端后台向授权服务器申请令牌;
- 授权服务器校验授权码后,向客户端发送访问令牌(Access Token)和更新令牌(Refresh Token)并重新定向到上一步指定的页面
3.2 简化模式
简化模式是指不通过客户端的后台服务器来获取访问令牌,这里的客户端通常是浏览器,客户端直接通过脚本语言(如JavaScript)来完成向授权服务器申请访问令牌的操作。
具体步骤如下:
- 用户访问客户端,客户端将用户引导到授权服务器上,并附加认证成功或失败时需要重定向的URI;
- 用户选择是否同意给客户端授权;
- 如用户同意授权,那么授权服务器根据user-agent中的数据进行验证,验证通过后将用户重定向到之前所指定的地址,同时在所重定向的地址中附加一个相应访问令牌的值;
- 浏览器将返回的信息保存在本地,然后向资源服务器发出请求,但不包括访问令牌;
- 资源服务器返回一个网页,通常在该网页中会包含一段代码,该代码可以获取之前返回的访问令牌;
- 浏览器执行上一步中获得的脚本,并获取到访问令牌;
- 浏览器将解析到的访问令牌发送给客户端
3.3 密码模式
密码模式是指客户端通过用户提供的用户名和密码信息,直接通过授权服务器来获取授权。在这种模式下,用户需要把自己的用户名和密码提供给客户端,但是客户端不得储存这些信息。该模式只有在用户对客户端高度信任的情况下或者同一个产品系列中应用。
该模式的授权流程如下:
- 用户向客户端提供相应的用户名和密码;
- 客户端通过用户提供的用户名和密码向授权服务器请求访问令牌;
- 授权服务器确认后,返回访问令牌给客户端
参考资料:
《Spring Cloud微服务架构开发实战》
http://www.ruanyifeng.com/blog/2019/04/oauth_design.html