OAuth 2.0 机制

本文档定义了 SASL XOAUTH2 机制,该机制可与 IMAP AUTHENTICATE、POP AUTH 和 SMTP AUTH 命令搭配使用。此机制允许使用 OAuth 2.0 访问令牌向用户的 Gmail 账号进行身份验证。

使用 OAuth 2.0

首先,请熟悉使用 OAuth 2.0 访问 Google API。该文档介绍了 OAuth 2.0 的工作原理,以及编写客户端所需的步骤。

您可能还想浏览示例 XOAUTH2 代码,了解有效的示例。

OAuth 2.0 范围

IMAP、POP 和 SMTP 访问权限的范围为 https://mail.google.com/。如果您为 IMAP、POP 或 SMTP 应用请求对完整邮件范围的访问权限,则该应用必须遵守我们的 Google API 服务:用户数据政策

  • 若要获得批准,您的应用必须充分利用 https://mail.google.com/
  • 如果您的应用不需要 https://mail.google.com/,请迁移到 Gmail API 并使用更精细的受限范围

Google Workspace 全网域授权

如果您打算使用Google Workspace 全网域授权,通过服务账号经由 IMAP 访问 Google Workspace 用户的邮箱,则可以使用 https://www.googleapis.com/auth/gmail.imap_admin 范围授权您的客户端。

如果使用此范围进行授权,IMAP 连接的行为会有所不同:

  • 即使用户在 Gmail 设置中停用了标签的“在 IMAP 中显示”设置,所有标签也会通过 IMAP 显示。
  • 无论用户在 Gmail 设置中将“文件夹大小限制”设置为何值,所有邮件都会通过 IMAP 显示。

SASL XOAUTH2 机制

借助 XOAUTH2 机制,客户端可以向服务器发送 OAuth 2.0 访问令牌。该协议使用以下各部分中所示的编码值。

初始客户端响应

SASL XOAUTH2 初始客户端响应的格式如下:

base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")

使用 RFC 4648 中定义的 base64 编码机制。^A 表示 Control+A (\001)。

例如,在进行 base64 编码之前,初始客户端响应可能如下所示:

user=someuser@example.com^Aauth=Bearer ya29.vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg^A^A

经过 base64 编码后,此字符串变为(为了清楚起见,我们使用了换行符):

dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52
YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cBAQ==

错误响应

如果初始客户端响应导致错误,服务器会发送一条包含错误消息的质询,格式如下:

base64({JSON-Body})

JSON-Body 包含三个值:statusschemesscope。例如:

eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb3BlIjoiaHR0cHM6Ly9t
YWlsLmdvb2dsZS5jb20vIn0K

经过 base64 解码后,此字符串变为(为清晰起见,已进行格式化):

{
  "status":"401",
  "schemes":"bearer",
  "scope":"https://mail.google.com/"
}

SASL 协议要求客户端针对此质询发送空响应。

IMAP 协议交换

本部分介绍了如何将 SASL XOAUTH2 与 Gmail IMAP 服务器搭配使用。

初始客户端响应

如需使用 SASL XOAUTH2 机制登录,客户端会调用 AUTHENTICATE 命令,并将机制参数设为 XOAUTH2,并将初始客户端响应设为如上所述。例如:

[connection begins]
C: C01 CAPABILITY
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2 AUTH=XOAUTH
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvb
QFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG
1semRHRXVZMjl0Q2cBAQ==
S: A01 OK Success
[connection continues...]

关于 IMAP 协议交换,请注意以下事项:

  • IMAP AUTHENTICATE 命令的文档位于 RFC 3501 中。
  • SASL-IR 功能允许在 AUTHENTICATE 命令的第一行中发送初始客户端响应,这样只需一次往返即可完成身份验证。RFC 4959 中记录了 SASL-IR。
  • AUTH=XOAUTH2 功能声明服务器支持本文档定义的 SASL 机制,并且通过将 XOAUTH2 指定为 AUTHENTICATE 命令的第一个实参来激活此机制。
  • AUTHENTICATECAPABILITY 命令中的换行符是为了便于理解,在实际命令数据中不会出现。整个 base64 实参应是一个连续的字符串,不含嵌入的空格,这样整个 AUTHENTICATE 命令就由一行文本组成。

错误响应

身份验证失败也会通过 IMAP AUTHENTICATE 命令返回:

[connection begins]
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQ
FhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1s
emRHRXVZMjl0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: A01 NO SASL authentication failed

关于 IMAP 协议交换,请注意以下事项:

  • 客户端向包含错误消息的质询发送空响应 ("\r\n")。

POP 协议交换

本部分介绍了如何将 SASL XOAUTH2 与 Gmail POP 服务器搭配使用。

初始客户端响应

如需使用 SASL XOAUTH2 机制登录,客户端会调用 AUTH 命令,并将机制参数设为 XOAUTH2,并将初始客户端响应设为如上所述。例如:

[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYX
JlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0
Q2cBAQ==
S: +OK Welcome.
[connection continues...]

关于 POP 协议交换的注意事项:

  • POP AUTH 命令的文档位于 RFC 1734 中。
  • AUTH 命令中的换行符是为了清晰起见,实际命令数据中不会有这些换行符。整个 base64 实参应是一个连续的字符串,不含嵌入的空格,这样整个 AUTH 命令就由一行文本组成。

错误响应

身份验证失败也会通过 POP AUTH 命令返回:

[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUi
OiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==

SMTP 协议交换

本部分介绍了如何将 SASL XOAUTH2 与 Gmail SMTP 服务器搭配使用。

初始客户端响应

如需使用 XOAUTH2 机制登录,客户端会调用 AUTH 命令,并将机制参数设置为 XOAUTH2,并使用上述方式构建初始客户端响应。例如:

[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: 235 2.7.0 Accepted
[connection continues...]

关于 SMTP 协议交换,请注意以下事项:

  • SMTP AUTH 命令记录在 RFC 4954 中。
  • AUTH 命令中的换行符是为了清晰起见,实际命令数据中不会有这些换行符。整个 base64 实参应是一个连续的字符串,不含嵌入的空格,这样整个 AUTH 命令就由一行文本组成。

错误响应

身份验证失败也会通过 SMTP AUTH 命令返回:

[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJl
ciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cB
AQ==
S: 334 eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: 535-5.7.1 Username and Password not accepted. Learn more at
S: 535 5.7.1 https://support.google.com/mail/?p=BadCredentials hx9sm5317360pbc.68
[connection continues...]

关于 SMTP 协议交换,请注意以下事项:

  • 客户端向包含错误消息的质询发送空响应 ("\r\n")。

参考