public Result <CredentialCreateOptions> MakeCredentialOptions(int userId, string username, string displayName, long loginId) { var user = new Fido2User { Name = username, DisplayName = displayName, Id = BitConverter.GetBytes(userId) }; var authenticatorSelection = new AuthenticatorSelection { UserVerification = UserVerificationRequirement.Required }; //var extensions = new AuthenticationExtensionsClientInputs //{ // Extensions = true, // UserVerificationIndex = true, // Location = true, // UserVerificationMethod = true, // BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds // { // FAR = float.MaxValue, // FRR = float.MaxValue // } //}; var options = _fido2.RequestNewCredential(user, null, authenticatorSelection, AttestationConveyancePreference.Direct); _cache.Set($"CredentialOptions:{loginId}", options, _options.Value.ChallengeExpiration); _logger.LogInformation($"Created options for login {loginId}"); return(Result.Success(options)); }
public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { if (string.IsNullOrEmpty(username)) { username = $"{displayName} (Usernameless user created at {DateTime.UtcNow})"; } // 1. Get user from DB by username (in our example, auto create missing users) var user = DemoStorage.GetOrAddUser(username, () => new Fido2User { DisplayName = displayName, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username var existingKeys = DemoStorage.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationMethod = true, }; var options = _fido2.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public async Task <CredentialCreateOptions> StartWebAuthnRegistrationAsync(User user) { var providers = user.GetTwoFactorProviders(); if (providers == null) { providers = new Dictionary <TwoFactorProviderType, TwoFactorProvider>(); } var provider = user.GetTwoFactorProvider(TwoFactorProviderType.WebAuthn); if (provider == null) { provider = new TwoFactorProvider { Enabled = false }; } if (provider.MetaData == null) { provider.MetaData = new Dictionary <string, object>(); } var fidoUser = new Fido2User { DisplayName = user.Name, Name = user.Email, Id = user.Id.ToByteArray(), }; var excludeCredentials = provider.MetaData .Where(k => k.Key.StartsWith("Key")) .Select(k => new TwoFactorProvider.WebAuthnData((dynamic)k.Value).Descriptor) .ToList(); var authenticatorSelection = new AuthenticatorSelection { AuthenticatorAttachment = null, RequireResidentKey = false, UserVerification = UserVerificationRequirement.Discouraged }; var options = _fido2.RequestNewCredential(fidoUser, excludeCredentials, authenticatorSelection, AttestationConveyancePreference.None); provider.MetaData["pending"] = options.ToJson(); providers[TwoFactorProviderType.WebAuthn] = provider; user.SetTwoFactorProviders(providers); await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.WebAuthn, false); return(options); }
public ActionResult CredentialOptions([FromBody] RegisterModel model) { var user = new Fido2User { DisplayName = $"{model.FirstName} {model.LastName}", Name = model.Email, Id = Encoding.UTF8.GetBytes(model.Email) }; var options = fido2.RequestNewCredential(user, new List <PublicKeyCredentialDescriptor>()); HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); return(Json(options)); }
public async Task <CredentialCreateOptions> RequestCreation(string userId) { await using var dbContext = _contextFactory.CreateContext(); var user = await dbContext.Users.Include(applicationUser => applicationUser.Fido2Credentials) .FirstOrDefaultAsync(applicationUser => applicationUser.Id == userId); if (user == null) { return(null); } // 2. Get user existing keys by username var existingKeys = user.Fido2Credentials .Where(credential => credential.Type == Fido2Credential.CredentialType.FIDO2) .Select(c => c.GetFido2Blob().Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = false, UserVerification = UserVerificationRequirement.Preferred }; var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue }, }; var options = _fido2.RequestNewCredential( new Fido2User() { DisplayName = user.UserName, Name = user.UserName, Id = user.Id.ToBytesUTF8() }, existingKeys, authenticatorSelection, AttestationConveyancePreference.None, exts); // options.Rp = new PublicKeyCredentialRpEntity(Request.Host.Host, options.Rp.Name, ""); CreationStore.AddOrReplace(userId, options); return(options); }
/// <summary> /// <para>注册:创建证明选项</para> /// <param name="opts"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public CredentialCreateOptions MakeCredentialOptions(User user, MakeCredentialParams opts) { var fidoUser = opts.GetFido2UserByUser(); // Create options var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationMethod = true, }; var existingKeys = GetPublicKeyCredentialDescriptors(user.UserId); var options = _fido2.RequestNewCredential( fidoUser, existingKeys, opts.AuthenticatorSelection, opts.Attestation, exts); distributedCache.SetString(user.UserId.ToString() + "attestationOptions", options.ToJson(), 120); return(options); }
public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { // user must already exist in Identity var identityUser = _users.FindByUsername(username); if (identityUser == null) { throw new Exception("User not found"); } if (!HttpContext.User.IsAuthenticated()) { throw new Exception("User is not authenticated"); } ; // 1. Get user from DB by username (in our example, auto create missing users) var user = PasswordlessStore.GetOrAddUser(username, () => new Fido2User { DisplayName = displayName, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username var existingKeys = PasswordlessStore.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _fido2.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public async Task <ActionResult <CredentialCreateOptions> > MakeCredentialOptions(CredentialOption option) { try { // 註冊使用者 var user = await context.Members.Where(x => x.UserName == option.UserName).FirstOrDefaultAsync(); if (user == null) { user = new Member { MemberId = Guid.NewGuid(), UserName = option.UserName, DisplayName = option.DisplayName, UserId = Encoding.UTF8.GetBytes(option.UserName) }; context.Members.Add(user); await context.SaveChangesAsync(); } var fidoUser = new Fido2User { DisplayName = user.DisplayName, Name = user.UserName, Id = user.UserId }; // 取得 Key. 排除已經註冊過的 Credentials var existingKeys = await context.StoredCredentials.Where(x => x.UserId == user.UserId).Select(x => x.Descriptor).ToListAsync(); // 建立 Option var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = option.RequireResidentKey, UserVerification = option.UserVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(option.AuthType)) { authenticatorSelection.AuthenticatorAttachment = option.AuthType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _fido2.RequestNewCredential(fidoUser, existingKeys, authenticatorSelection, option.AttType.ToEnum <AttestationConveyancePreference>(), exts); // Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 回傳 return(Ok(options)); } catch (Exception e) { return(BadRequest(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public async Task <JsonResult> MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { var applicationUser = await _userManager.GetUserAsync(HttpContext.User); // 1. Get user from DB by username (in our example, auto create missing users) var user = new Fido2User { Id = Encoding.UTF8.GetBytes(applicationUser.Id) // byte representation of userID is required }; // 2. Get user existing keys by username // var existingKeys = DemoStorage.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); var existingKeys = new List <PublicKeyCredentialDescriptor>(); //_fido2CredentialService.GetCredentialsByUser(applicationUser).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _fido2.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }