项目地址
后端
前端 Demo (Angular)
注:demo账户:用户名root@gmail.com密码root
背景
鉴于已经有大量关于 OAuth2的文章,本文主要是笔者进行实践当中的心得与笔记,并不会太深入OAuth2协议的细节。千言万语都在代码中,如有不足之处,请在评论区留言或者在GitHub issue中反馈。
项目简介
oauth2service是一个基于spring boot + security oauth2 + jwt的oauth2认证授权微服务。项目提供Client和Resource Owner的相关api操作接口,并且提供了定制化的Authorization code以实现完整的前后端分离。你可以在docker中方便的下载打包好的镜像,并且轻松的启动它。除此之外,配套的swagger文档可以来帮助你通过swagger editor直接调用api。项目有比较全面的测试覆盖,可以根据你自己的需求进行定制或者改动。
技术术语
- Authentication(验证): 你是不是我的用户?
- Authorization(授权):虽然你是我的用户,但是我给予了你什么操作权限 ?第一方应用授权用户或者用户授权第三方应用来执行特定的操作。
- First Party : 我是用户的所有者,我是第一方应用
- Third Party : 第三方应用,我只想获得用户的一部分内容,我并不是用户的所有者
- OAuth2 : 一个Authentication和Authorization的协议,致力于将用户的登录信息(用户名与密码)集中管理,并且在不需要传输登录信息的前提下,允许Third Party获取用户授权的内容。
- Client : 这里并不是指用户而是任何应用程序包括第一方和第三方
- Resource Owner :用户
- Authorization(Authentication)Server : 对尝试登录用户进行Authentication和Authorization
- 的服务端
- Resource Server : 用户所拥有的资源,资源服务
- Client Credentials flow : 任何应用程序通过ID和Secret来登录,你可以把它当作机器用户
- Password flow : Client Credentials +用户名与密码。用户通过Client(这里是第一方应用)登录
- Authorization code flow : 最常见的应用场景,在用户已登录的状态下授权第三方应用获得用户资源
- Implicit flow : 这个已经不再推荐
- Refresh token flow : 与Password flow联合使用来避免用户频繁登录
注:Client credentials flow 并不可以添加这个选项,如果token过期,一般要求Client带着ID和Secret再请求一次token。
- JWT : 全称JSON web token,是一个经过Authorization(Authentication)Server签名的token
- Asymmetric key : 非对称加密,通过一个公匙和私匙来保证公匙加密的信息只有私匙可以解密
- JWT + Asymmetric key这样资源服务器不需要存储public key只需要在启动时向Authorization server索取即可
- JWT vs Session已经有很多关于此的讨论,这里我们采取用时间(CPU)换空间 (Memory)。值得一提的是Session作为一个广泛应用的技术,有成熟的方案可供参考,建议据自己的需求来选择。JWT有天然的无状态、易于伸缩的优点但是对于token回收以及控制方面有着明显的缺点(在将来的release笔者会重点尝试解决这个问题)。
一些需要注意的地方
- JWT里有什么?
JWT中的信息并不是加密传输,所以任何敏感信息不可以放在JWT中(当然你也可以添加额外的加密手段)。信息主要包括Client的ID和 权限信息,以及允许访问的资源ID,如果是用户那么用户名称也会被包括,并且用户的权限信息会取代Client的权限信息。
- 资源服务器是如何被保护?
首先你需要配置资源服务器,添加相关的dependency, 在启动时,服务器会向认证服务器索取public key以用来验证收到的JWT,并根据解码的信息(注意这里并不是解密,因为JWT的payload是base64编码的)来判断是否处理请求。
注:笔者会在之后更新具体的操作方法(添坑)
- 我应该选择哪个flow ?
注:笔者个人认为即使是第一方应用,如果需要获取用户的特定资源还是采取authorization code flow较为合适,这样有利于保持一个较为统一的管理接口,你可以设置为自动批准来提升用户体验(项目目前并不支持自动批准)。
OAuth2应用场景
OAuth2的主要应用场景,例如你通过GitHub来登录第三方应用,你授权第三方应用权限来获取你的一些GitHub资源,这样以后再登录(准确来讲是再授权),第三方应用便用这些资源来识别你。在这里第三方应用并不知道你的登录名密码,它只存有你授权获得的资源。