コード例 #1
0
        public async Task <CredentialMakeResult> MakeCredential([Required, FromBody] MakeCredentialsRequest request)
        {
            using (AuthLogic.Disable())
            {
                var optionsEntity = Database.Retrieve <WebAuthnMakeCredentialsOptionsEntity>(request.CreateOptionsId);

                var options = CredentialCreateOptions.FromJson(optionsEntity.Json);

                var result = await fido2.MakeNewCredentialAsync(request.AttestationRawResponse, options, async (args) =>
                {
                    return(!(await Database.Query <WebAuthnCredentialEntity>().AnyAsync(c => c.CredentialId == args.CredentialId)));
                });

                if (result.Status != "ok")
                {
                    throw new InvalidOperationException(options.ErrorMessage);
                }

                new WebAuthnCredentialEntity
                {
                    CredentialId = result.Result.CredentialId,
                    PublicKey    = result.Result.PublicKey,
                    User         = Lite.ParsePrimaryKey <UserEntity>(Encoding.UTF8.GetString(result.Result.User.Id)),
                    Counter      = (int)result.Result.Counter,
                    CredType     = result.Result.CredType,
                    Aaguid       = result.Result.Aaguid,
                }.Save();

                return(result);
            }
        }
コード例 #2
0
        public async Task <JsonResult> MakeCredentialResultTest([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            // 1. get the options we sent the client
            var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
            var options     = CredentialCreateOptions.FromJson(jsonOptions);

            // 2. Create callback so that lib can verify credential id is unique to this user
            IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
            {
                var users = await DemoStorage.GetUsersByCredentialIdAsync(args.CredentialId);

                if (users.Count > 0)
                {
                    return(false);
                }

                return(true);
            };

            // 2. Verify and make the credentials
            var success = await _lib.MakeNewCredentialAsync(attestationResponse, options, callback);

            // 3. Store the credentials in db
            DemoStorage.AddCredentialToUser(options.User, new StoredCredential
            {
                Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                PublicKey        = success.Result.PublicKey,
                UserHandle       = success.Result.User.Id,
                SignatureCounter = success.Result.Counter
            });

            // 4. return "ok" to the client
            return(Json(success));
        }
コード例 #3
0
        public async Task <JsonResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse attestationResponse, CancellationToken cancellationToken)
        {
            try
            {
                // 1. get the options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = static async(args, cancellationToken) =>
コード例 #4
0
        /// <summary>
        /// 注册:验证用户凭证
        /// <para>当客户端返回响应时,我们验证并注册凭据。</para>
        /// </summary>
        /// <param name="attestationResponse"></param>
        public async Task <CredentialMakeResult> RegisterCredentials(User user, string fido2Name, AuthenticatorAttestationRawResponse attestationResponse)
        {
            // 1. get the options we sent the client
            var jsonOptions = distributedCache.GetString(user.UserId.ToString() + "attestationOptions");

            if (string.IsNullOrEmpty(jsonOptions))
            {
                return(null);
            }
            var options = CredentialCreateOptions.FromJson(jsonOptions);

            // 2. Create callback so that lib can verify credential id is unique to this user
            IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
            {
                //var users = await DemoStorage.GetUsersByCredentialIdAsync(args.CredentialId);
                //if (users.Count > 0)
                //    return false;
                var argUserId = args.CredentialId;
                if (this.dataContext.FIDO2Repository.Where(b => b.CredentialId.Equals(argUserId)).Any())
                {
                    return(false);
                }
                return(true);
            };
            // 2. Verify and make the credentials
            var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback);

            // 3. Store the credentials in db
            //var user = dataContext.User.Where(b => b.UserId == userId).FirstOrDefault();
            if (user == null)
            {
                return(null);
            }
            var fido2 = new FIDO2Item()
            {
                Id               = IdGenerator.NextId(),
                UserId           = user.UserId,
                FIDO2Name        = fido2Name,
                CredentialId     = success.Result.CredentialId,
                PublicKey        = success.Result.PublicKey,
                UserHandle       = success.Result.User.Id,
                SignatureCounter = success.Result.Counter,
                CredType         = success.Result.CredType,
                RegDate          = DateTime.Now,
                AaGuid           = success.Result.Aaguid
            };

            dataContext.FIDO2Repository.Add(fido2);

            dataContext.SaveChanges();

            return(success);
        }
コード例 #5
0
        public async Task <ActionResult <CredentialMakeResult> > MakeCredential(AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                // 1. get the options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var credentialIdString = Base64Url.Encode(args.CredentialId);
                    var cred = await context.StoredCredentials.Where(x => x.DescriptorJson.Contains(credentialIdString)).FirstOrDefaultAsync();

                    if (cred == null)
                    {
                        return(true);
                    }
                    var users = await context.Members.Where(x => x.UserId == cred.UserId).Select(u => new Fido2User
                    {
                        DisplayName = u.DisplayName,
                        Name        = u.UserName,
                        Id          = u.UserId
                    }).ToListAsync();

                    return(users.Count == 0);
                };

                // 2. Verify and make the credentials
                var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback);

                context.StoredCredentials.Add(new StoredCredential
                {
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    UserId           = options.User.Id,
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });
                await context.SaveChangesAsync();

                return(Ok(success));
            }
            catch (Exception e)
            {
                return(BadRequest(new CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
コード例 #6
0
        public async Task <IActionResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            var o = new
            {
                challenge = string.Empty,
                origin    = string.Empty,
                type      = string.Empty
            };

            var username = string.Empty;

            try
            {
                o = JsonConvert.DeserializeAnonymousType((Encoding.UTF8.GetString(attestationResponse.Response.ClientDataJson)), o);
                var jsonOptions = _memoryCache.Get <string>(o.challenge);
                var options     = CredentialCreateOptions.FromJson(jsonOptions);
                username = options.User.Name;

                async Task <bool> Callback(IsCredentialIdUniqueToUserParams args)
                {
                    var users = await _dataStore.GetUsersByCredentialIdAsync(args.CredentialId);

                    return(users.Count <= 0);
                }

                var success = await _lib.MakeNewCredentialAsync(attestationResponse, options, Callback);

                _dataStore.AddCredentialToUser(options.User, new StoredCredential
                {
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                var ev = new Event(username, "Successfully logged the person in", nameof(RegistrationController), nameof(MakeCredential));
                await _elasticClient.IndexAsync(ev, i => i.Index(GetIndexName(nameof(Ok))));

                return(Ok(success));
            }
            catch (Exception e)
            {
                var errorEvent = new ErrorEvent(e, username, nameof(RegistrationController), nameof(MakeCredential));
                await _elasticClient.IndexAsync(errorEvent, i => i.Index(GetIndexName(nameof(Exception))));

                return(Ok(new Fido2.CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e) + $"ClientDataJson = {Encoding.UTF8.GetString(attestationResponse.Response.ClientDataJson)}"
                }));
            }
        }
コード例 #7
0
        public async Task <ActionResult> MakeCredential([ModelBinder(typeof(NewtonsoftJsonAdapter.Binder))] MakeCredentialRequest request)
        {
            var subjectId = User.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;

            try
            {
                // 1. get the options we sent the client
                var jsonOptions = TestUsers.FidoAttestationOptions[request.SessionId];
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Verify and make the credentials
                var success = await _lib.MakeNewCredentialAsync(
                    attestationResponse : request.AttestationResponse,
                    origChallenge : options,
                    isCredentialIdUniqueToUser : async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var users = TestUsers.FidoCredentials.Where(c => c.Descriptor.Id.SequenceEqual(args.CredentialId)).ToList();
                    if (users.Count > 0)
                    {
                        return(false);
                    }

                    return(true);
                });

                // 3. Store the credentials in db
                TestUsers.FidoCredentials.Add(new TestUsers.StoredFidoCredential
                {
                    UserId           = options.User.Id,
                    SubjectId        = subjectId,
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                // 4. return "ok" to the client
                return(Ok(success));
            }
            catch (Exception e)
            {
                return(BadRequest(new CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
コード例 #8
0
        public async Task <IActionResult> CompleteAuthDeviceRegistration(
            [FromBody] CompleteAuthDeviceRegistrationRequest model)
        {
            var jsonOptions = this.TempData["CredentialData"] as string;
            var options     = CredentialCreateOptions.FromJson(jsonOptions);

            var result = await this._mediator.Send(new EnrollAuthenticatorDeviceCommand(
                                                       model.Name,
                                                       model.AttestationResponse,
                                                       options));

            return(this.Json(result.IsFailure
                ? new CompleteAuthDeviceRegistrationResponse()
                : new CompleteAuthDeviceRegistrationResponse(result.Value.CredentialMakeResult, result.Value.DeviceId, model.Name)));
        }
コード例 #9
0
        public async Task <ActionResult> MakeCredential(
            [FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                // 1. get the options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var users = await fidoStore.GetUsersByCredentialIdAsync(args.CredentialId);

                    if (users.Count > 0)
                    {
                        return(false);
                    }

                    return(true);
                };

                // 2. Verify and make the credentials
                var success = await fido2.MakeNewCredentialAsync(attestationResponse, options, callback);

                // 3. Store the credentials in db
                fidoStore.AddCredentialToUser(options.User, new StoredCredential
                {
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                // 4. return "ok" to the client
                return(Ok(success));
            }
            catch (Exception e)
            {
                return(BadRequest(new Fido2.CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
コード例 #10
0
        public async Task <JsonResult> SaveCredentials([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                var fidoCredentials = await fido2.MakeNewCredentialAsync(attestationResponse, options, IsCredentialUnique);

                var storedCredential = new StoredCredential
                {
                    Descriptor       = new PublicKeyCredentialDescriptor(fidoCredentials.Result.CredentialId),
                    PublicKey        = fidoCredentials.Result.PublicKey,
                    UserHandle       = fidoCredentials.Result.User.Id,
                    SignatureCounter = fidoCredentials.Result.Counter,
                    CredType         = fidoCredentials.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = fidoCredentials.Result.Aaguid
                };

                var names  = options.User.DisplayName.Split(' ');
                var result = await oktaClient.Users.CreateUserAsync(new CreateUserWithoutCredentialsOptions
                {
                    Profile = new UserProfile
                    {
                        Login                     = options.User.Name,
                        Email                     = options.User.Name,
                        DisplayName               = options.User.DisplayName,
                        FirstName                 = names[0],
                        LastName                  = names[1],
                        ["CredentialId"]          = Convert.ToBase64String(fidoCredentials.Result.CredentialId),
                        ["PasswordlessPublicKey"] = JsonConvert.SerializeObject(storedCredential)
                    }
                });

                return(Json(fidoCredentials));
            }
            catch (Exception e)
            {
                return(Json(new Fido2.CredentialMakeResult {
                    Status = "error", ErrorMessage = e.Message
                }));
            }
        }
コード例 #11
0
        public async Task <IActionResult> CompleteAuthDeviceRegistration(
            [FromBody] CompleteAuthDeviceRegistrationRequest model)
        {
            var jsonOptions = this.TempData["CredentialData"] as string;
            var options     = CredentialCreateOptions.FromJson(jsonOptions);

            var result = await this._mediator.Send(new EnrollDeviceCommand(
                                                       model.Name,
                                                       model.AttestationResponse,
                                                       options));

            if (result.IsFailure)
            {
                return(this.Json(new Fido2.CredentialMakeResult {
                    Status = "error"
                }));
            }


            return(this.Json(result.Value.CredentialMakeResult));
        }
コード例 #12
0
ファイル: UserService.cs プロジェクト: nitinj19/server
        public async Task <bool> CompleteWebAuthRegistrationAsync(User user, int id, string name, AuthenticatorAttestationRawResponse attestationResponse)
        {
            var keyId = $"Key{id}";

            var provider = user.GetTwoFactorProvider(TwoFactorProviderType.WebAuthn);

            if (!provider?.MetaData?.ContainsKey("pending") ?? true)
            {
                return(false);
            }

            var options = CredentialCreateOptions.FromJson((string)provider.MetaData["pending"]);

            // Callback to ensure credential id is unique. Always return true since we don't care if another
            // account uses the same 2fa key.
            IsCredentialIdUniqueToUserAsyncDelegate callback = args => Task.FromResult(true);

            var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback);

            provider.MetaData.Remove("pending");
            provider.MetaData[keyId] = new TwoFactorProvider.WebAuthnData
            {
                Name             = name,
                Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                PublicKey        = success.Result.PublicKey,
                UserHandle       = success.Result.User.Id,
                SignatureCounter = success.Result.Counter,
                CredType         = success.Result.CredType,
                RegDate          = DateTime.Now,
                AaGuid           = success.Result.Aaguid
            };

            var providers = user.GetTwoFactorProviders();

            providers[TwoFactorProviderType.WebAuthn] = provider;
            user.SetTwoFactorProviders(providers);
            await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.WebAuthn);

            return(true);
        }
コード例 #13
0
        public async Task <JsonResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse authenticatorAttestationRawResponse)
        {
            try
            {
                var user = await _userManager.GetUserAsync(User);

                if (user == null)
                {
                    throw new Exception("Unable to retrieve user.");
                }

                var jsonOptions = await _distributedCache.GetStringAsync(UniqueId);

                if (string.IsNullOrEmpty(jsonOptions))
                {
                    throw new Exception("Cant get Credential options from cache.");
                }
                var options = CredentialCreateOptions.FromJson(jsonOptions);

                IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUserAsyncDelegate = async(IsCredentialIdUniqueToUserParams isCredentialIdUniqueToUserParams) =>
                {
                    var fido2Users = await _fido2Service.GetFido2UsersByCredentialIdAsync(isCredentialIdUniqueToUserParams.CredentialId);

                    if (fido2Users.Count > 0)
                    {
                        return(false);
                    }
                    return(true);
                };
                var result = await _fido2.MakeNewCredentialAsync(authenticatorAttestationRawResponse, options, isCredentialIdUniqueToUserAsyncDelegate);

                if (result.Status != "ok")
                {
                    throw new Exception("Unable to create credential.");
                }


                var newFido2StoredCredential = new Fido2StoredCredential {
                };
                newFido2StoredCredential.UserName         = options.User.Name;
                newFido2StoredCredential.UserId           = options.User.Id;
                newFido2StoredCredential.PublicKey        = result.Result.PublicKey;
                newFido2StoredCredential.UserHandle       = result.Result.User.Id;
                newFido2StoredCredential.SignatureCounter = result.Result.Counter;
                newFido2StoredCredential.CredType         = result.Result.CredType;
                newFido2StoredCredential.RegDate          = DateTime.Now;
                newFido2StoredCredential.AaGuid           = Guid.NewGuid();
                newFido2StoredCredential.Descriptor       = new PublicKeyCredentialDescriptor(result.Result.CredentialId);

                _fido2Service.AddFido2StoredCredential(newFido2StoredCredential);

                return(Json(result));
            }
            catch (Exception exception)
            {
                return(Json(new CredentialCreateOptions()
                {
                    Status = "error", ErrorMessage = CommonFunctions.FormatException(exception)
                }));
            }
        }
コード例 #14
0
        public async Task <IActionResult> RegisterCallback([FromBody] AuthenticatorAttestationRawResponse model)
        {
            var sub = HttpContext.User.Claims.FirstOrDefault(x => x.Type == "sub")?.Value;

            if (string.IsNullOrEmpty(sub))
            {
                return(RedirectToAction("Index", "Home"));
            }
            var user = await _users.FindByIdAsync(sub);

            if (user == null)
            {
                return(RedirectToAction("Index", "Home"));
            }

            try
            {
                // 1. get the options we sent the client
                var jsonOptions       = HttpContext.Session.GetString("fido2.attestationOptions");
                var options           = CredentialCreateOptions.FromJson(jsonOptions);
                var authenticatorName = HttpContext.Session.GetString("fido2.attestationOptions.authenticatorType");
                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var users = _authContext.FidoLogins.Where(l => l.PublicKeyIdBytes.SequenceEqual(args.CredentialId));
                    if (users.Count() > 0)
                    {
                        return(false);
                    }

                    return(true);
                };

                // 2. Verify and make the credentials
                var success = await _lib.MakeNewCredentialAsync(model, options, callback);

                var parsedResponse = AuthenticatorAttestationResponse.Parse(model);;
                var authData       = new AuthenticatorData(parsedResponse.AttestationObject.AuthData);
                var dbUser         = _authContext.Users.First(x => x.Id == user.Id);
                dbUser.TwoFactorEnabled = true;
                var login = new FidoLogin()
                {
                    PublicKeyIdBytes  = success.Result.CredentialId,
                    PublicKeyId       = Fido2NetLib.Base64Url.Encode(success.Result.CredentialId),
                    AaGuid            = success.Result.Aaguid.ToString(),
                    PublicKey         = success.Result.PublicKey,
                    SignatureCounter  = success.Result.Counter,
                    CredType          = success.Result.CredType,
                    RegistrationDate  = DateTime.Now,
                    User              = dbUser,
                    UserHandle        = success.Result.User.Id,
                    AuthenticatorName = authenticatorName
                };
                _authContext.FidoLogins.Add(login);
                _authContext.SaveChanges();


                // 4. return "ok" to the client
                return(Json(new { success = true }));
            }
            catch (Exception e)
            {
                return(Json(new { error = true }));
            }
        }
コード例 #15
0
        public async Task <JsonResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                // 1. get the options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var users = await _fido2Storage.GetUsersByCredentialIdAsync(args.CredentialId);

                    if (users.Count > 0)
                    {
                        return(false);
                    }

                    return(true);
                };

                // 2. Verify and make the credentials
                var success = await _lib.MakeNewCredentialAsync(attestationResponse, options, callback);

                // 3. Store the credentials in db
                await _fido2Storage.AddCredentialToUser(options.User, new FidoStoredCredential
                {
                    Username         = options.User.Name,
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                // 4. return "ok" to the client

                var user = await _userManager.GetUserAsync(User);

                if (user == null)
                {
                    return(Json(new CredentialMakeResult {
                        Status = "error", ErrorMessage = _sharedLocalizer["FIDO2_USER_NOTFOUND", _userManager.GetUserId(User)]
                    }));
                }

                await _userManager.SetTwoFactorEnabledAsync(user, true);

                var userId = await _userManager.GetUserIdAsync(user);

                return(Json(success));
            }
            catch (Exception e)
            {
                return(Json(new CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
コード例 #16
0
        public async Task <JsonResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                // 1. get the options we sent the client
                //var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var jsonOptions = await _distributedCache.GetStringAsync(UniqueId);

                if (string.IsNullOrEmpty(jsonOptions))
                {
                    throw new Exception("Can't get CredentialOptions from cache");
                }
                var options = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    var users = await _fido2Storage.GetUsersByCredentialIdAsync(args.CredentialId);

                    if (users.Count > 0)
                    {
                        return(false);
                    }

                    return(true);
                };

                // 2. Verify and make the credentials
                var success = await _lib.MakeNewCredentialAsync(attestationResponse, options, callback);

                // 3. Store the credentials in db
                await _fido2Storage.AddCredentialToUser(options.User, new FidoStoredCredential
                {
                    Username         = options.User.Name,
                    Descriptor       = new PublicKeyCredentialDescriptor(success.Result.CredentialId),
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                // 4. return "ok" to the client
                var user = await _userManager.GetUserAsync(User);

                if (user == null)
                {
                    return(Json(new CredentialMakeResult {
                        Status = "error", ErrorMessage = $"Unable to load user with ID '{_userManager.GetUserId(User)}'."
                    }));
                }

                await _userManager.SetTwoFactorEnabledAsync(user, true);

                if (await _userManager.CountRecoveryCodesAsync(user) == 0)
                {
                    var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);

                    RecoveryCodes = recoveryCodes.ToArray();
                }

                return(Json(success));
            }
            catch (Exception e)
            {
                return(Json(new CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
コード例 #17
0
        public async Task <JsonResult> MakeCredential([FromBody] AuthenticatorAttestationRawResponse attestationResponse)
        {
            try
            {
                // 1. get the options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.attestationOptions");
                var options     = CredentialCreateOptions.FromJson(jsonOptions);

                // 2. Create callback so that lib can verify credential id is unique to this user
                // IsCredentialIdUniqueToUserAsyncDelegate callback = async (IsCredentialIdUniqueToUserParams args) =>
                // {
                //   // var users = await DemoStorage.GetUsersByCredentialIdAsync(args.CredentialId);
                //   var users = await _fido2CredentialService.GetUsersByCredentialIdAsync(args.CredentialId);
                //   if (users.Count > 0)
                //     return false;
                //
                //   return true;
                // };
                IsCredentialIdUniqueToUserAsyncDelegate callback = async(IsCredentialIdUniqueToUserParams args) =>
                {
                    // TODO Check if credentials are unique
                    return(true);
                };

                // 2. Verify and make the credentials
                var success = await _fido2.MakeNewCredentialAsync(attestationResponse, options, callback);


                var applicationUser = await _userManager.GetUserAsync(HttpContext.User);

                // Schreibe die Credentials in die Datenbank
                var newFido2Credential = await _fido2CredentialService.AddCredentialToUser(new Fido2Credential()
                {
                    UserId           = applicationUser.Id,
                    Descriptor       = success.Result.CredentialId,
                    PublicKey        = success.Result.PublicKey,
                    UserHandle       = success.Result.User.Id,
                    SignatureCounter = success.Result.Counter,
                    CredType         = success.Result.CredType,
                    RegDate          = DateTime.Now,
                    AaGuid           = success.Result.Aaguid
                });

                // applicationUser.Fido2Credentials.Add(newFido2Credential);
                applicationUser.TwoFactorEnabled = true;
                applicationUser.TwoFactorMethod  = TwoFactorType.Fido2;
                await _userManager.UpdateAsync(applicationUser);

                // TODO Return Databse Entry not just JSON


                // 4. return "ok" to the client
                return(new JsonResult(success));
            }
            catch (Exception e)
            {
                return(new JsonResult(new Fido2.CredentialMakeResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }