Delphi WebAuthn 服务器
为您的 Delphi 服务器添加基于通行密钥的无密码身份验证。WebAuthn Level 2 / FIDO2 注册和认证仪式、证明验证、凭据存储钩子。
为您的 Delphi 服务器添加基于通行密钥的无密码身份验证。WebAuthn Level 2 / FIDO2 注册和认证仪式、证明验证、凭据存储钩子。
实现 WebAuthn 依赖方服务器端 — 创建凭据挑战、验证 navigator.credentials 响应、解析证明声明并验证断言签名。
TsgcWSAPIServer_WebAuthn
Windows, macOS, Linux, iOS, Android
Enterprise
将 TsgcWSAPIServer_WebAuthn 放置于 TsgcWebSocketHTTPServer 上,设置 WebAuthnOptions.RelyingParty,然后通过 OnWebAuthnRegistrationSuccessful 存储每个新的通行密钥,并通过 OnWebAuthnAuthenticationGetCredential 在登录时重新加载它。
uses
sgcWebSocket, sgcWebSocket_Server_APIs, sgcWebAuthn_Classes;
// Server:TsgcWebSocketHTTPServer 和 WebAuthn:TsgcWSAPIServer_WebAuthn 是窗体字段
procedure TForm1.StartServer;
begin
Server := TsgcWebSocketHTTPServer.Create(nil);
Server.Port := 8443;
Server.SSL := True;
Server.SSLOptions.CertFile := 'server.pem';
Server.SSLOptions.KeyFile := 'server.pem';
Server.SSLOptions.Port := 8443;
WebAuthn := TsgcWSAPIServer_WebAuthn.Create(nil);
WebAuthn.Server := Server;
WebAuthn.WebAuthnOptions.RelyingParty := 'example.com';
WebAuthn.OnWebAuthnRegistrationSuccessful := OnRegistrationSuccessful;
WebAuthn.OnWebAuthnAuthenticationGetCredential := OnGetCredential;
Server.Active := True;
end;
procedure TForm1.OnRegistrationSuccessful(Sender: TObject;
const aRegistration: TsgcWebAuthn_Registration;
const aCredentialRecord: TsgcWebAuthn_CredentialRecord; var Accept: Boolean);
begin
// 将新的通行密钥存储到您自己的数据库中
SaveCredential(aCredentialRecord.CredentialId, aCredentialRecord.AsJSON);
end;
procedure TForm1.OnGetCredential(Sender: TObject; const aCredentialId: string;
const aCredentialRecord: TsgcWebAuthn_CredentialRecord; var Found: Boolean);
var
vJSON: string;
begin
// 登录时:重新加载已存储的通行密钥
vJSON := LoadCredential(aCredentialId);
Found := vJSON <> '';
if Found then
aCredentialRecord.ReadJSON(vJSON);
end;
// uses: sgcWebSocket, sgcWebSocket_Server_APIs
TsgcWebSocketHTTPServer *Server = new TsgcWebSocketHTTPServer(this);
TsgcWSAPIServer_WebAuthn *WebAuthn = new TsgcWSAPIServer_WebAuthn(this);
WebAuthn->Server = Server;
WebAuthn->WebAuthnOptions->RelyingParty = "example.com";
Server->Active = true;
将 Delphi 进程变为通行密钥感知身份验证端点的依赖方服务器。
OnWebAuthnRegistrationOptionsRequest 接收对 PublicKeyCredentialCreationOptions 的请求;浏览器调用 navigator.credentials.create();服务器验证证明,OnWebAuthnRegistrationSuccessful 返回新的凭据记录。
OnWebAuthnAuthenticationOptionsRequest 使用先前存储的凭据记录填充 PublicKeyCredentialRequestOptions;服务器使用存储的公钥验证断言签名,并触发 OnWebAuthnAuthenticationSuccessful。
支持 none、packed、fido-u2f、tpm、android-key、android-safetynet 和 apple 证明声明格式。
跟踪每个凭据的 signCount 以检测克隆的身份验证器。如果计数器回退,OnWebAuthnAuthenticationError 将报告您可以处理的错误。
UserVerification 可按仪式设置为 required、preferred 或 discouraged — 验证步骤强制执行该选择。
OnWebAuthnAuthenticationOptionsRequest 将请求交给您,以便为正在进行的登录返回正确的 CredentialRecords,用于 allowCredentials 列表。存储方式由您自行设计。
本组件所实现标准的权威来源。
通行密钥是一种可被发现的 WebAuthn 凭据,由 Windows Hello、iCloud 钥匙串、Google 密码管理器或安全密钥保存。该服务器支持完整的通行密钥体验,同时凭据始终保存在您自己的数据库中。
在不提供用户名的情况下请求身份验证选项。浏览器会列出它为您的站点保存的通行密钥,用户选择其中之一,服务器随后校验返回的 userHandle。
启用条件中介后,通行密钥会出现在用户名字段的自动填充列表中。添加 autocomplete="username webauthn",并从 /sgcWebAuthn.js 调用 startAuthentication(options, true)。
可在笔记本电脑上注册一个通行密钥,在手机上注册另一个。同一账户的所有通行密钥共享一个用户句柄,身份验证选项会列出其中的每一个。
凭据记录中的 BackupEligible 和 BackupState 用于区分同步型通行密钥与设备绑定型安全密钥,方便您向只有一台设备的用户建议注册第二个通行密钥。
在 OnWebAuthnRegistrationSuccessful 中保存记录,在 OnWebAuthnAuthenticationGetCredential 中为无用户名或自动填充登录查找凭据,并在 OnWebAuthnAuthenticationSuccessful 中保存新的计数器。
签名计数器未向前推进时会被判定为可能的克隆并遭拒绝,备份资格标志在两次登录之间发生变化时同样会被拒绝。始终报告 0 的同步型通行密钥不受影响,仍可正常使用。
阅读 Delphi 中的通行密钥:使用 WebAuthn 实现无密码登录,以及 Passkeys 帮助主题。