MyBlog

OAuth2, OIDC与SSO

last modified: 2022-05-24 10:31

概念 中文 作用
OAuth 2.0​ 授权框架 解决“授权”问题:让第三方应用有权访问用户在资源服务器(如Twitter)的特定资源(如发帖、评论)。
OpenID Connect (OIDC)​ 认证协议 解决“认证”问题:在OAuth 2.0之上构建,让第三方应用能确认用户的身份(证明“你是你”)。如Google SSO场景。

OAuth2交互流程

oauth2

  • Resource Owner(用户) 核心职责:拥有受保护资源,并有权授权第三方应用访问这些资源。

  • Client(第三方应用) 核心职责:试图代表资源持有方去访问受保护资源的一方。​ 它需要获得用户的授权。

  • Authorization Server 核心职责:在成功验证资源持有方的身份并获得其授权后,向第三方应用颁发访问令牌(access_token)。​ 这是OAuth 2.0流程中的核心枢纽。

  • Resource Server(隐含的第四个角色,通常是与Authorization Server合二为一) 核心职责:托管受保护资源的服务器。​ 它接收并验证第三方应用提供的访问令牌,然后决定是否返回其请求的资源。

OAuth2单独使用场景(授权第三方应用管理其Twitter账号)

oauth2

OAuth2与OIDC组合使用场景(企业内部利用Google账号进行单点登录SSO)

oauth2

核心安全设计

为什么需要State参数?

State参数是一个由Client(第三方应用)生成的随机字符串,用于防止CSRF攻击。

在OAuth2.0的授权流程中,Client会生成一个State参数,并将其包含在授权请求中。当用户授权后,Authorization Server会返回一个授权码Code,并将其包含在授权响应中。Client会使用这个授权码Code来换取访问令牌(access_token)。

如果Client没有生成State参数,那么攻击者可以伪造授权请求,替换授权码Code为攻击者伪造的授权码,从而获取攻击者伪造的访问令牌(access_token)。

下例中,攻击者将Code替换为自己github账号的Code,从而实现攻击者github账号绑定到用户mynotes服务(第三方服务)的账号上。

oauth2

正确使用了State参数的方式:

oauth2

为什么需要Code参数?

授权码Code是个短时效、一次性使用的授权凭证,它的作用是作为一个中间凭证,让Client能够安全地从Authorization Server那里换取真正的访问令牌(access_token),而无需将更敏感的app_secret暴露给前端。

一种伪装成OAuth2.0的邪修

伪装的OAuth2.0流程,用于在三方应用中管理WhatsApps等APP的消息(如Tanka):

oauth2

消息加解密流程:

Step1 设备注册与密钥生成

你向WhatsApp注册自己的公钥:

oauth2

Step2 消息发送的加密流程(从服务A发出)

你发消息给Alice:

oauth2

Step3 消息接收的解密流程(发往服务A)

Bob发消息给你:

oauth2