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! TokenCredential) {
throw const AuthException('Unsupported credential for token auth');
}
TokenGrant? matched;
// Iterate all entries with a constant-time comparison so a wrong token does
// not short-circuit and reveal information through timing.
for (final entry in _tokens.entries) {
if (_constantTimeEquals(entry.key, credential.token)) {
matched = entry.value;
}
}
if (matched == null) {
throw const AuthException('Invalid token');
}
if (matched.principal.value != credential.principal) {
throw const AuthException('Token does not match principal');
}
return Principal(
id: matched.principal,
displayName: matched.displayName.isEmpty
? matched.principal.value
: matched.displayName,
roles: matched.roles,
);
}