Tuesday, 06 May 2025
  11 Replies
  55 Visits
  Subscribe
Hello,

I am currently integrating the Webauthn things into the existing gateway that is based on TsgcWebSocketHTTPServer.

I create all components in Code, perhaps this causes my problems. First I create the Webserver:

FWebServer := TsgcWebSocketHTTPServer.Create(Self);
FWebServer.Name := 'FWebServer';

then I create

FAuthnServer := TsgcWSAPIServer_WebAuthn.Create(Self);
with FAuthnServer do
begin
Name := 'FAuthnServer';
with WebAuthnOptions do
begin
RelyingParty := FDomain;
// These are taken from the esegece example that works well with Windows, IOS and Android
Algorithms := [waunalgES256, waunalgRS256];
AttestationPolicy.NoneAttestation := true;
AttestationPolicy.SelfAttestation := true;
AttestationPolicy.PackedAttestation := true;
AttestationPolicy.TPMAttestation := true;
AttestationPolicy.AndroidKeyAttestation := true;
AttestationPolicy.AppleAttestation := true;
AttestationPolicy.FidoU2FAttestation := true;
Credentials.AllowCredentials := false;
Origins.AllowCrossOrigins := false;
TimeOut := 60000;
AllowSignCountLessOrEqualStoredValue := false;
end;
With EndpointsOptions do
begin
AuthenticationOptions.Endpoint := '/authoptions';
AuthenticationOptions.Enabled := true;
AuthenticationVerify.Endpoint := '/authverify';
AuthenticationVerify.Enabled := true;
RegistrationOptions.Endpoint := '/regoptions';
RegistrationOptions.Enabled := true;
RegistrationVerify.Endpoint := '/regverify';
RegistrationVerify.Enabled := true;
WebAuthn.Endpoint := 'assets/js/webauthn.js';
WebAuthn.Enabled := true;
end;
OnWebAuthnAuthenticationError := WebAuthnServerWebAuthnAuthenticationError;
OnWebAuthnException := WebAuthnServerWebAuthnException;
OnWebAuthnAuthenticationOptionsRequest := WebAuthnServerWebAuthnAuthenticationOptionsRequest;
OnWebAuthnAuthenticationSuccessful := WebAuthnServerWebAuthnAuthenticationSuccessful;
OnWebAuthnRegistrationSuccessful := WebAuthnServerWebAuthnRegistrationSuccessful;
OnWebAuthnException := WebAuthnServerWebAuthnException;
Server := FWebServer;
end;

I Then configure the Webserver

with FWebServer do
begin

port := FINI.readInteger('web', 'port', 9989);
KeepAlive := false;
MaxConnections := 0;
NotifyEvents := neAsynchronous;
port := FINI.readInteger('web', 'port', 9989);
Bindings.Clear;
Bindings.add;
Bindings[0].port := FINI.readInteger('web', 'port', 9989);
Bindings[0].IP := FINI.readString('web', 'ip', '127.0.0.1');
if FWithSSL then
begin
ssl := true;
with SSLOptions do
begin
OpenSSL_Options.CipherList :=
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS';
VerifyCertificate := false;
CertFile := TPath.combine(FRootPath, 'appcert.pem');
KeyFile := TPath.combine(FRootPath, 'appkey.pem');
RootCertFile := TPath.combine(FRootPath, 'approot.pem');
OpenSSL_Options.LibPathCustom := FRootPath;
OpenSSL_Options.LibPath := oslpCustomPath;
OpenSSL_Options.APIVersion := TwsOpenSSLAPI.oslAPI_3_0;
SSLOptions.Version := tls1_2;
end;
end;
Authentication.URL.Enabled := true;
Authentication.Session.Enabled := true;
HTTP2Options.Enabled := true;
Options.JavascriptFiles := true;
ThreadPool := true;
OnCommandGet := webServerCommandGet;
SessionTimeOut := 15 * 60 * 1000;
SessionState := true;
AutoStartSession := true;
end;

// We acticate here to involve the attaches Authn and Push Servers too
FWebServer.Active := true;

In webServerCommandGet I leave all authn things alone:

// These are served by the webauthn component
if (ARequestInfo.uri = '/regoptions') or (ARequestInfo.uri = '/regverify') or (ARequestInfo.uri = '/authoptions') or
(ARequestInfo.uri = '/authverify') or
(ARequestInfo.uri = '/assets/js/webauthn.js') then
exit;

If i call e.g. /regoptions I get an error that a username must be given thrown by the webauthn component.

But if I call it from Javascript:

async function initBio() {
try {
console.log("Starting regoptions");
const resp = await fetch('/regoptions', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: localStorage.getItem("lastuser"),
algorithms: []
}),
});

console.log("answer:", resp);
const data = await resp.json();
console.log("data:", data);
} catch (err) {
console.error("error in /regoptions:", err);
}
...

This await never returns. The Javascript file is loaded.

Are there any special settings I have to apply to the webserver component?

Any Help is very appreciated.

Best regards, Michael