Delphi PKCE OAuth2

· 功能

sgcWebSockets 2024.5.0 起,支持 PKCE(代码交换证明密钥,Proof of Key Code Exchange),这是 OAuth 2.0 协议的扩展,有助于防止代码拦截攻击。

PKCE 在 OAuth2 服务器客户端组件上均受支持。

什么是 PKCE

PKCE(代码交换证明密钥)是 OAuth 2.0 的安全增强机制,旨在防止公共或原生应用程序中的授权码拦截攻击。它在 RFC 7636 中有详细说明,作为缓解"授权码拦截"漏洞的技术,特别适用于无法可靠保密客户端密钥的环境,例如移动或客户端应用程序。

在典型的 OAuth 2.0 授权码授权流程中,客户端应用程序通过将用户重定向到授权服务器来获取授权码,然后用该码换取访问令牌。但是,如果攻击者拦截了授权码,他们可能会利用它来获取访问令牌并访问受保护的资源。

PKCE 通过引入证明密钥机制来解决此风险。PKCE 的关键组成部分是:


PKCE 流程如下所示:

  1. 客户端应用程序生成代码验证器,并从中派生代码挑战。
  2. 客户端应用程序发起 OAuth 授权请求,包含代码挑战和代码挑战方法(plain 或 S256)。
  3. 用户授予访问权限后,授权服务器将授权码发送给客户端。
  4. 客户端应用程序将授权码发送到令牌端点以换取访问令牌时,同时包含代码验证器。
  5. 授权服务器通过应用与创建代码挑战时相同的转换方法来验证代码验证器,并检查其是否与存储的代码挑战匹配。
  6. 如果验证成功,授权服务器颁发访问令牌;否则,请求将被拒绝。

此机制确保只有拥有原始代码验证器的客户端才能成功将授权码换取访问令牌,在 OAuth 流程中提供了强大的安全保障。

Delphi OAuth2 客户端

TsgcHTTP_OAuth2_Client 组件支持授权码 + PKCE 流程,要使用此授权类型,请将 GrantType 属性设置为 auth2CodePKCE

oAuth2 := TsgcHTTP2_OAuth2.Create(nil);
oAuth2.LocalServerOptions.Host := '127.0.0.1';
oAuth2.LocalServerOptions.Port := 8080;
oAuth2.AuthorizationServerOptions.AuthURL := 'https://accounts.google.com/o/oauth2/auth';
oAuth2.AuthorizationServerOptions.TokenURL := 'https://accounts.google.com/o/oauth2/token';
oAuth2.AuthorizationServerOptions.Scope.Add('https://mail.google.com/');
oAuth2.OAuth2Options.ClientId := '180803918357-eqjtn20gqfhcs6gjkebbrrenh022mqqc.apps.googleusercontent.com';
oAuth2.OAuth2Options.ClientSecret := '_by0iYYrvVHxC2Z8TbtNEYQN';
oAuth2.OAuth2Options.GrantType := auth2CodePKCE;
procedure OnOAuth2AfterAccessToken(Sender: TObject; const Access_Token, Token_Type, Expires_In,
  Refresh_Token, Scope, RawParams: string; var Handled: Boolean);
begin
  <...>
  <...>
end;
oAuth2.OnAfterAccessToken := OnOAuth2AfterAccessToken;
oAuth2.Start;

Delphi OAuth2 服务器

TsgcHTTP_OAuth2_Server 组件默认支持 PKCE(尽管可以在 OAuth2Options.PKCE 属性中禁用)。当服务器检测到 OAuth2 客户端正在使用 PKCE 时,将验证 PKCE 值是否有效,若无效则在响应中返回错误。

以下是关于如何使用 Delphi OAuth2 服务器的链接:

https://www.esegece.com/help/sgcWebSockets/#t=Components%2FHTTP%2FAuthorization%2FOAuth2%2Fserver%2FQuickStart%2FOAuth2_Server_Example.htm