【OAuth2系列】如何使用OAuth 2.0实现安全授权?详解四种授权方式

2,452 阅读16分钟

作者:后端小肥肠

🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案

🍊 有疑问可私信或评论区联系我。

🥑  创作不易未经允许严禁转载。

姊妹篇:

【OAuth2系列】集成微信小程序登录到 Spring Security OAuth 2.0_spring security 微信小程序登录-CSDN博客

【OAuth2系列】Spring Cloud Gateway 作为OAuth2 Client接入第三方单点登录代码实践_spring gateway oauth2 client-CSDN博客

【Spring Security系列】5 次密码错误触发账号锁定?Spring Security 高效实现方案详解_springsecurity5.7.6自定义密码错误策略-CSDN博客

【Spring Security系列】10分钟实现 SpringSecurity + CAS 完美单点登录方案_spring-security-cas-CSDN博客

【Spring Security系列】如何用Spring Security集成手机验证码登录?五分钟搞定!_springsecurity短信验证码登录-CSDN博客

【Spring Security系列】基于Spring Security实现权限动态分配之菜单-角色分配及动态鉴权实践_spring secrity权限角色动态管理-CSDN博客

【Spring Security系列】基于Spring Security实现权限动态分配之用户-角色分配_spring security 角色-CSDN博客

【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索_spring security 微信小程序登录-CSDN博客

【Spring Security系列】Spring Security+JWT+Redis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客

1. 前言

随着互联网的快速发展,用户数据的安全性和隐私保护变得尤为重要。为了解决第三方应用在访问用户资源时可能出现的安全问题,OAuth 2.0 成为当前最广泛使用的授权协议。它提供了一种安全、开放、标准化的方式,允许用户授权第三方应用访问其资源,而无需暴露敏感的账户信息。无论是常见的社交登录(如微信、Google 登录),还是系统间的安全对接,OAuth 2.0 都为现代应用程序提供了强大的支持。

在本文中,我们将全面解析 OAuth 2.0 的授权机制和应用场景,包括常用的四种授权方式。通过实际的例子和详细的流程分析,希望能够帮助开发者快速掌握 OAuth 2.0 的核心概念和实现方法。

2.什么是OAuth2?

oauth.net/2/

OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的规范标准。与以往的授权方式不同之处是OAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 OAuth 是开放的安全的,业界提供了 OAuth 的多种实现,如 Java、PHP、Ruby 等各种语言开发包,大大节约了程序员的时间,因而OAuth是简易的。很多大公司如 阿里、腾讯、 Google,Yahoo,Microsoft等都提供了 OAuth 认证服务,这些都足以说明 OAuth 标准逐渐成为开放资源授权的标准。OAuth 协议1.0版本过于复杂,目前发展到2.0版本,2.0版本已得到广泛应用。

3. OAuth 2.0 的授权方式应用场景

在实际开发中,OAuth 2.0 提供了灵活的授权机制,可以满足多种场景需求。为了更好地说明其使用方式,我们以一个在线教育平台为例,结合中国本土服务,探讨 OAuth 2.0 的实际应用。

假设某在线教育平台需要整合第三方服务(如微信、钉钉、腾讯会议等),以实现以下功能:

  • 学生通过微信授权登录并绑定学习日程到腾讯日历;
  • 教师使用钉钉账号快速登录教学管理工具,查看课程安排和学员信息;
  • 平台自动对接腾讯会议,为线上课堂创建和管理视频会议。

OAuth 2.0 在这个场景中可以帮助平台完成以下任务:

用户授权第三方访问资源:学生希望将自己的学习日程同步到腾讯日历,但又不希望直接向平台提供腾讯账号和密码。通过 OAuth 2.0,学生可以在平台中点击“同步到腾讯日历”,系统跳转到腾讯的授权页面,学生登录并授权后,平台获取一个访问令牌。之后,平台通过访问令牌与腾讯日历 API 交互,完成学习日程的同步。

OAuth 2.0 在在线教育平台中的应用 - visual selection (1).png

快速实现身份验证: 教师可以通过 OAuth 2.0 快速登录教学管理工具,无需专门注册在线教育平台的账号。例如,教师点击“使用钉钉登录”,系统会跳转到钉钉的授权页面进行身份验证。在教师授权后,钉钉返回一个访问令牌,平台据此确认用户身份并分配相应的权限(如查看课程安排、学员列表等)。

OAuth 2.0 在在线教育平台中的应用 - visual selection (2).png

系统间安全对接: 在线教育平台需要与腾讯会议集成,以便为线上课堂创建视频会议。在这种系统对系统的交互中,OAuth 2.0 的客户端模式(Client Credentials Grant)可以实现平台和腾讯会议 API 的安全通信。平台通过提供自身的客户端凭据(如 Client ID 和 Client Secret)获取访问令牌,然后使用该令牌通过腾讯会议的接口完成会议的创建、更新或删除等操作。

OAuth 2.0 在在线教育平台中的应用 - visual selection (3).png

通过以上场景可以看出,OAuth 2.0 的授权机制在平台中可以灵活适配,从学生的日程同步到教师的快速登录,再到系统间的安全对接,均能确保数据的安全性和访问的便利性。

4. OAuth2.0中四种授权方式

OAuth2.0 的授权方式一共有四种:

授权码模式(Authorization Code): 功能最完整,流程最严密的授权模式。国内各大服务提供商(微信、QQ、微 博、淘宝 、百度)都采用此模式进行授权。可以确定是用户真正同意授权;而且令牌是认证服务器发放给第三方应用的服务器,而不是浏览器上。

简化模式(Implicit):  令牌是发放给浏览器的,oauth客户端运行在浏览器中 ,通过JS脚本去申请令牌。而不是发放给第三方应用的服务器。

密码模式(Resource Owner Password Credentials): 将用户名和密码传过去,直接获取 access_token 。用户同意授权动作是在第三方应用上完成 ,而不是在认证服务器上。第三方应用申请令牌时,直接带着用户名密码去向 认证服务器申请令牌。这种方式认证服务器无法断定用户是否真的授权了,用户名密码可能是第三方应用盗取来 的。

客户端证书模式(Client credentials): 用得少。当一个第三应用自己本身需要获取资源(而不是以用户的名 义),而不是获取用户的资源时,客户端模式十分有用。

OAuth 2.0 授权方式概述 - visual selection.png

4.1. 授权码模式

授权码模式是 OAuth 2.0 中一种常见的授权方式,适用于需要高度安全性、后端服务器参与的场景。以下是以 第三方网站 为例,结合流程图详细说明授权码模式的工作原理:

授权码模式.drawio.png

流程步骤

  1. 用户访问第三方网站资源并请求登录
    用户打开 第三方网站,尝试访问某些需要用户登录授权的资源。此时,系统会引导用户跳转到认证服务器(如微信认证服务器)。
  2. 跳转到认证服务器进行登录
    第三方网站 检测到用户未登录后,会将用户跳转到认证服务器(如微信认证服务器)的登录页面,要求用户进行身份验证。
  3. 用户登录并授权
    用户在认证服务器的页面完成登录操作后,认证服务器会向用户展示授权请求页面,说明 第三方网站 需要访问哪些权限(如获取用户的基本信息)。用户确认授权后,认证服务器记录授权并生成一个授权码。
  4. 认证服务器返回授权码
    授权码是一个临时的短期凭证,认证服务器会将其附带在用户跳转回 第三方网站 时的重定向 URI 中,并将其发送到 第三方网站 的客户端。
  5. 第三方网站使用授权码请求令牌
    第三方网站 的后端服务器拿到授权码后,会向认证服务器的令牌接口发送请求,并附上自身的 Client ID 和 Client Secret 以验证身份。
  6. 认证服务器返回访问令牌
    认证服务器验证授权码和客户端身份后,向 第三方网站 返回访问令牌(Access Token)。访问令牌是访问用户资源的凭证。
  7. 第三方网站使用令牌获取用户信息
    第三方网站 使用访问令牌向资源服务器(如微信资源服务器)发起请求,获取用户的授权资源(如用户基本信息)。
  8. 资源服务器返回用户信息
    资源服务器验证令牌合法性后,返回用户的授权信息(如用户名、邮箱等)给 第三方网站。
  9. 登录完成并显示用户信息
    第三方网站 获取到用户信息后,将其存储在会话中,视为登录成功,并向用户显示相关信息。

授权码模式的特点

  • 高安全性:授权码仅在短时间内有效,访问令牌只会在后端服务器存储,前端无法直接接触到敏感数据。
  • 适用场景:适用于 Web 应用或需要后端支持的场景,例如需要与外部服务整合的复杂应用。
  • 分工明确:前端负责引导用户登录授权,后端负责安全存储和使用访问令牌。

4.2. 简化模式

简化模式(Implicit Grant)是一种适用于 无后端支持 的客户端应用(如单页面应用,SPA)的授权方式。访问令牌直接返回给客户端,用于访问用户的资源。以下以 第三方单页面应用 为例,解析简化模式的流程。

流程步骤

  1. 用户访问单页面应用并请求登录
    用户打开 第三方单页面应用,尝试访问需要授权的资源(例如用户个人信息、数据等)。

  2. 跳转到认证服务器进行登录
    应用检测到用户未登录,会将用户引导至认证服务器的授权页面。此时,应用会携带 Client ID 和重定向 URI 等参数,表明这是一个授权请求。

  3. 用户登录并授权
    用户在认证服务器的页面完成登录操作后,系统会展示一个授权请求页面,说明单页面应用需要的权限范围(例如访问用户信息)。用户确认授权后,认证服务器会生成一个访问令牌(Access Token) 。

  4. 认证服务器直接返回访问令牌
    认证服务器将访问令牌附带在重定向 URI 的哈希片段中,直接返回给单页面应用的前端客户端。例如:

    https://example.com/callback#access_token=xyz123&token_type=bearer&expires_in=3600
    
  5. 单页面应用提取访问令牌并存储
    前端应用从重定向 URI 中提取出访问令牌(通常通过 JavaScript 处理),并将其存储在内存中或短期存储中(如浏览器的 sessionStorage)。

  6. 使用访问令牌请求资源服务器
    单页面应用使用访问令牌向资源服务器发起请求,获取用户的授权数据(如用户名、头像等)。

  7. 资源服务器返回授权数据
    资源服务器验证令牌合法性后,返回用户的授权数据给单页面应用。

  8. 完成登录并显示用户信息
    单页面应用根据返回的数据更新界面,显示用户的登录信息和授权内容。

简化模式的特点

  1. 无后端参与:令牌直接发送到客户端,适用于纯前端应用(如 SPA)。

  2. 快速响应:减少了后端交互的步骤,用户体验流畅。

  3. 安全性低:访问令牌暴露在前端,容易被拦截或盗用,建议配合以下措施:

    • 通过 HTTPS 确保传输安全。
    • 将令牌存储在短期存储(如 sessionStorage)中,而非长期存储(如 localStorage)。
    • 配合短期有效的令牌(如令牌有效期为 1 小时以内)。

4.3. 密码模式

密码模式(Resource Owner Password Credentials Grant)允许用户直接将用户名和密码提供给客户端,以获取访问令牌。它的安全性较低,一般仅在高度信任的环境中使用,比如内部系统。以下以 第三方网站的管理系统 为例,解析密码模式的流程。

流程步骤

  1. 用户在客户端输入凭据
    用户打开客户端应用(如第三方内部管理系统),并输入用户名和密码尝试登录。

  2. 客户端将凭据发送至认证服务器
    客户端应用将用户输入的 用户名 和 密码,连同自身的 Client ID 和 Client Secret,通过后台请求发送到认证服务器。

    请求参数示例:

    POST /oauth/token HTTP/1.1
    Host: auth-server.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=password
    username=user123
    password=pass123
    client_id=client_id_example
    client_secret=client_secret_example
    
  3. 认证服务器验证凭据
    认证服务器接收到请求后,会:

    • 验证 用户名 和 密码 是否正确。
    • 检查 Client ID 和 Client Secret 是否有效。
    • 如果所有验证通过,则生成一个访问令牌(Access Token)。
  4. 认证服务器返回访问令牌
    验证通过后,认证服务器返回访问令牌(Access Token)给客户端。

    返回示例:

    {
        "access_token": "xyz123",
        "token_type": "bearer",
        "expires_in": 3600
    }
    
  5. 客户端使用令牌请求资源服务器
    客户端携带访问令牌,向资源服务器发起请求,获取用户的授权数据或受保护的资源。

    请求示例:

    GET /userinfo HTTP/1.1
    Host: resource-server.com
    Authorization: Bearer xyz123
    
  6. 资源服务器返回授权数据
    资源服务器验证令牌的合法性后,返回用户授权的资源(如用户信息或操作权限)。

  7. 完成授权流程并展示数据
    客户端接收到用户数据后,展示相关内容(如登录成功后的用户信息)。

密码模式的特点

  • 用户凭据直接暴露:客户端需要直接存储用户名和密码,安全性较低。
  • 适用场景:适用于内部应用或高度信任的场景,如内部管理系统。
  • 不推荐用于公开的客户端应用:建议仅在无法避免的情况下使用。

4.4. 客户端模式 

客户端模式(Client Credentials Grant)用于服务之间的授权,不涉及用户参与。典型场景是服务端之间的通信,例如后台服务器与第三方 API 的对接。以下以 第三方网站 和 资源服务器 的对接为例,解析客户端模式的流程。

流程步骤

客户端模式.drawio.png
  1. 第三方网站向认证服务器发起请求
    第三方网站 的后台服务器向认证服务器发送请求,附带自身的 Client ID 和 Client Secret。
  2. 认证服务器验证客户端身份
    认证服务器验证客户端的 Client ID 和 Client Secret 是否正确,确认客户端的合法性。
  3. 认证服务器返回访问令牌
    验证通过后,认证服务器向 第三方网站 返回访问令牌(Access Token)。
  4. 第三方网站使用访问令牌访问资源服务器
    第三方网站 使用获取的访问令牌向资源服务器发起请求,获取所需的资源或数据(如服务状态、统计数据等)。
  5. 资源服务器返回授权数据
    资源服务器验证令牌合法性后,返回请求的数据给 第三方网站。

客户端模式的特点

  • 无用户参与:直接在服务之间完成授权,令牌只在后台使用。
  • 适用场景:服务对服务的交互,例如后台系统调用 API、任务自动化。
  • 安全性高:凭据和令牌存储在服务器端,减少了被窃取的风险。

5. 结语

OAuth 2.0 作为现代应用开发中重要的授权机制,为用户与第三方应用之间提供了安全可靠的授权方式。从授权码模式到简化模式,再到密码模式和客户端模式,每种方式都能灵活适配不同场景需求。通过合理选择授权模式并结合安全措施(如 HTTPS 和短期令牌),可以有效保障用户数据的安全性。希望本文能够帮助开发者快速理解 OAuth 2.0 的核心概念和实现,为构建安全可靠的应用提供指导。

结语3.jpg