| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- using System.Text;
- using System.Text.Json;
- using Fido2NetLib;
- using Fido2NetLib.Objects;
- namespace Passwordless;
- public class CredentialManager
- {
- private readonly IFido2 _fido2;
- private readonly OptionsCache _optionsCache;
- private readonly JsonSerializerOptions _jsonOptions;
- public CredentialManager(IFido2 fido2, OptionsCache optionsCache)
- {
- _fido2 = fido2;
- _optionsCache = optionsCache;
- _jsonOptions = new JsonSerializerOptions()
- {
- WriteIndented = true,
- };
- }
-
- public CredentialCreateOptions BuildCredentialOptions(string login)
- {
- var loginDisplay = Encoding.UTF8.GetString(Base64UrlConverter.Decode(login));
- var loginName = NameTransform.ToFileName(loginDisplay);
- var user = new Fido2User
- {
- DisplayName = loginDisplay,
- Id = Base64UrlConverter.Decode(login),
- Name = loginName,
- };
- var authenticatorSelection = new AuthenticatorSelection
- {
- UserVerification = UserVerificationRequirement.Discouraged,
- RequireResidentKey = false,
- };
- var extensions = new AuthenticationExtensionsClientInputs
- {
- Extensions = true,
- UserVerificationMethod = false,
- };
-
- var options = _fido2.RequestNewCredential(user, new List<PublicKeyCredentialDescriptor>(), authenticatorSelection, AttestationConveyancePreference.None, extensions);
- _optionsCache.Set(options);
-
- return options;
- }
- public async Task<Fido2.CredentialMakeResult> RegisterCredential(string login, AuthenticatorAttestationRawResponse attestationResponse)
- {
- // 2. Create callback so that lib can verify credential id is unique to this user
- static Task<bool> Callback(IsCredentialIdUniqueToUserParams args, CancellationToken cancellationToken)
- {
- return Task.FromResult(!File.Exists($"./data/{args.User.Name}"));
- }
- var loginDisplay = Encoding.UTF8.GetString(Base64UrlConverter.Decode(login));
- var loginName = NameTransform.ToFileName(loginDisplay);
- var options = _optionsCache.Get(loginName);
- var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, Callback);
- if (success.Status == "ok")
- {
- await using var fileStream = File.OpenWrite($"./data/{success.Result!.User.Name}.json");
- await JsonSerializer.SerializeAsync(fileStream, success.Result, _jsonOptions);
- }
-
- return success;
- }
- }
|