authenticate method
Authenticates credential, returning the resolved Principal.
challenge is the per-connection nonce the Hub issued in its hello;
public-key authenticators verify the signature against it for replay
protection, while token authenticators ignore it.
Throws AuthException if the credential is unsupported, malformed, unknown or fails verification.
Implementation
@override
Future<Principal> authenticate(
Credential credential, {
required Uint8List challenge,
}) async {
if (credential is! PublicKeyCredential) {
throw const AuthException('Unsupported credential for public-key auth');
}
final Ed25519PublicKey publicKey;
try {
publicKey = Ed25519PublicKey.fromBase64(credential.publicKeyBase64);
} on Object {
throw const AuthException('Malformed public key');
}
final entry = store.find(credential.principal, publicKey);
if (entry == null) {
throw const AuthException('Public key not authorized for principal');
}
final List<int> signatureBytes;
try {
signatureBytes = base64.decode(
base64.normalize(_toStandard(credential.signatureBase64)),
);
} on Object {
throw const AuthException('Malformed signature');
}
final valid = await _algorithm.verify(
challenge,
signature: Signature(
signatureBytes,
publicKey: SimplePublicKey(publicKey.bytes, type: KeyPairType.ed25519),
),
);
if (!valid) {
throw const AuthException('Signature verification failed');
}
return Principal(
id: PrincipalId(credential.principal),
displayName: entry.displayName.isEmpty
? credential.principal
: entry.displayName,
roles: entry.roles,
);
}