protected override void Dispose(bool disposing)
            {
                AssertionOptions.AssertEquivalencyUsing(options => new EquivalencyAssertionOptions());
                AssertionOptions.IsValueType = defaultValueTypePredicate;

                base.Dispose(disposing);
            }
        /// <summary>
        /// Asserts that a collection of objects is equivalent to another collection of objects.
        /// </summary>
        /// <remarks>
        /// The two collections are equivalent when they both contain the same strings in any order.
        /// </remarks>
        /// <param name="config">
        /// A reference to the <see cref="EquivalencyAssertionOptions{String}"/> configuration object that can be used
        /// to influence the way the object graphs are compared. You can also provide an alternative instance of the
        /// <see cref="EquivalencyAssertionOptions{String}"/> class. The global defaults are determined by the
        /// <see cref="AssertionOptions"/> class.
        /// </param>
        /// <param name="because">
        /// An optional formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the
        /// assertion is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
        /// </param>
        /// <param name="becauseArgs">
        /// Zero or more objects to format using the placeholders in <see cref="because" />.
        /// </param>
        public AndConstraint <StringCollectionAssertions> BeEquivalentTo(IEnumerable <string> expectation,
                                                                         Func <EquivalencyAssertionOptions <string>, EquivalencyAssertionOptions <string> > config, string because = "",
                                                                         params object[] becauseArgs)
        {
            Guard.ThrowIfArgumentIsNull(config, nameof(config));

            EquivalencyAssertionOptions <IEnumerable <string> > options = config(AssertionOptions.CloneDefaults <string>()).AsCollection();

            var context = new EquivalencyValidationContext
            {
                Subject          = Subject,
                Expectation      = expectation,
                RootIsCollection = true,
                CompileTimeType  = typeof(IEnumerable <string>),
                Because          = because,
                BecauseArgs      = becauseArgs,
                Tracer           = options.TraceWriter
            };

            var equivalencyValidator = new EquivalencyValidator(options);

            equivalencyValidator.AssertEquality(context);

            return(new AndConstraint <StringCollectionAssertions>(this));
        }
 public static void UsePrecision(double precision = DefaultPrecision)
 {
     AssertionOptions.AssertEquivalencyUsing(
         options => options
         .Using <double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, precision))
         .WhenTypeIs <double>());
 }
        private object BuildObject(Random r, TypeBuilder typeBuilder, bool isGraph)
        {
            if (isGraph && _createdObjects.TryGetValue(typeBuilder, out var existing))
            {
                return(existing);
            }

            if (!_createdTypes.TryGetValue(typeBuilder, out var t))
            {
                t = typeBuilder.CreateType() !;

                if (t.IsValueType)
                {
                    AssertionOptions.AssertEquivalencyUsing(x => { x.GetType().GetMethod("ComparingByMembers").MakeGenericMethod(t).Invoke(x, null); return(x); });
                }

                _createdTypes.Add(typeBuilder, t);
            }

            var result = Activator.CreateInstance(t !) !;

            if (isGraph)
            {
                _createdObjects.Add(typeBuilder, result);
            }

            PopulateObject(r, result, t, isGraph);

            return(result);
        }
        public void Constructor_GiveValidArguments_PropertiesAreSet()
        {
            var assertionOptions = new AssertionOptions();
            var result           = new DeviceMfaRequestCommandResult(assertionOptions);

            Assert.Equal(assertionOptions, result.AssertionOptions);
        }
示例#6
0
        /// <summary>
        /// 断言:创建断言选项
        /// <para> 当用户想要登录时,我们会根据注册的凭据进行断言。</para>
        /// </summary>
        public async Task <AssertionOptions> AssertionOptionsPost(User user, AssertionClientParams assertionClientParams)
        {
            string error = "";

            // 1. Get user from DB
            if (user == null)
            {
                error = "username was not registered";
                var ass = new AssertionOptions()
                {
                    Status       = "bad",
                    ErrorMessage = error
                };
                return(ass);
            }
            // 2. Get registered credentials from database

            var existingCredentials = GetPublicKeyCredentialDescriptors(user.UserId);

            var options = _fido2.GetAssertionOptions(
                existingCredentials,
                assertionClientParams.UserVerification,
                assertionClientParams.Extensions
                );

            distributedCache.SetString(user.UserId.ToString() + "assertionOptions", options.ToJson(), 120);

            return(options);
        }
        static BinaryEncoderTests()
        {
            // Qualified name
            AssertionOptions.AssertEquivalencyUsing(options => options.ComparingByMembers <QualifiedName>());

            // Localizable text
            AssertionOptions.AssertEquivalencyUsing(options => options.ComparingByMembers <LocalizedText>());

            // StatusCode
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new StatusCodeEquivalency()));

            // Variant
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new VariantEquivalency()));

            // NodeId
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new NodeIdEquivalency()));

            // ExpandedNodeId
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new ExpandedNodeIdEquivalency()));

            // DiagnosticInfo
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new DiagnosticInfoEquivalency()));

            // DataValue
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new DataValueEquivalency()));

            // Xml
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new XmlEquivalency()));

            // Matrix/Multidim array
            AssertionOptions.AssertEquivalencyUsing(options => options.Using(new MatrixEquivalency()));
        }
示例#8
0
        public async Task <JsonResult> SignIn([FromBody] AuthenticatorAssertionRawResponse clientResponse)
        {
            try
            {
                var jsonOptions = HttpContext.Session.GetString("fido2.assertionOptions");
                var options     = AssertionOptions.FromJson(jsonOptions);

                var user = await GetUserByCredentials(clientResponse.Id);

                var credential = JsonConvert.DeserializeObject <StoredCredential>(user.Profile["PasswordlessPublicKey"].ToString());

                var result = await fido2.MakeAssertionAsync(clientResponse, options, credential.PublicKey, credential.SignatureCounter,
                                                            args => Task.FromResult(credential.UserHandle.SequenceEqual(args.UserHandle)));

                await UpdateCounter(user, credential, result.Counter);

                var claims = new List <Claim>
                {
                    new Claim(ClaimTypes.Name, user.Profile.Email)
                };

                var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));

                return(Json(result));
            }
            catch (Exception e)
            {
                return(Json(new AssertionVerificationResult {
                    Status = "error", ErrorMessage = e.Message
                }));
            }
        }
示例#9
0
        public async Task <JsonResult> MakeAssertionTest([FromBody] AuthenticatorAssertionRawResponse clientResponse)
        {
            // 1. Get the assertion options we sent the client
            var jsonOptions = HttpContext.Session.GetString("fido2.assertionOptions");
            var options     = AssertionOptions.FromJson(jsonOptions);

            // 2. Get registered credential from database
            var creds = DemoStorage.GetCredentialById(clientResponse.Id);

            // 3. Get credential counter from database
            var storedCounter = creds.SignatureCounter;

            // 4. Create callback to check if userhandle owns the credentialId
            IsUserHandleOwnerOfCredentialIdAsync callback = async(args) =>
            {
                var storedCreds = await DemoStorage.GetCredentialsByUserHandleAsync(args.UserHandle);

                return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId)));
            };

            // 5. Make the assertion
            var res = await _lib.MakeAssertionAsync(clientResponse, options, creds.PublicKey, storedCounter, callback);

            // 6. Store the updated counter
            DemoStorage.UpdateCounter(res.CredentialId, res.Counter);

            var testRes = new
            {
                status       = "ok",
                errorMessage = ""
            };

            // 7. return OK to client
            return(Json(testRes));
        }
示例#10
0
        public CartTest()
        {
            var mock = new MockRepository(MockBehavior.Strict);

            productRepository = mock.Create <DataRepository <Product> >();
            cartRepository    = mock.Create <DataRepository <Cart> >();

            var products = new List <Product>
            {
                new Product {
                    Id = 1, Name = "soap", UnitPrice = 10,
                },
            };

            productRepository.Setup(repo => repo.Get(It.IsAny <int>()))
            .Returns <int>(id => products.FirstOrDefault(p => p.Id == id));

            cartController = new CartController(productRepository.Object, cartRepository.Object, new Api.Logic());

            AssertionOptions.AssertEquivalencyUsing(options =>
            {
                options.WithoutStrictOrdering();
                return(options);
            });
        }
示例#11
0
 public void OneTimeSetUp() => AssertionOptions.AssertEquivalencyUsing(options =>
 {
     options.Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation, 1000)).WhenTypeIs <DateTime>();
     options.Using <DateTimeOffset>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation, 1000)).WhenTypeIs <DateTimeOffset>();
     options.Using <decimal>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, 0.00000000000001M)).WhenTypeIs <decimal>();
     return(options);
 });
        public static AndConstraint <ObjectAssertions> BeJsonSerializable <T>(this ObjectAssertions assertions, Func <EquivalencyAssertionOptions <T>, EquivalencyAssertionOptions <T> > options, string because = "", params object[] becauseArgs)
        {
            Execute.Assertion.ForCondition(assertions.Subject != null)
            .BecauseOf(because, becauseArgs)
            .FailWith("Expected {context:object} to be JSON serializable{reason}, but the value is null.  Please provide a value for the assertion.");

            Execute.Assertion.ForCondition(assertions.Subject is T)
            .BecauseOf(because, becauseArgs)
            .FailWith("Expected {context:object} to be JSON serializable{reason}, but {context:object} is not assignable to {0}", typeof(T));

            try
            {
                var deserializedObject = CreateCloneUsingJsonSerializer(assertions.Subject);

                var defaultOptions = AssertionOptions.CloneDefaults <T>()
                                     .RespectingRuntimeTypes()
                                     .IncludingFields()
                                     .IncludingProperties();

                var typedSubject = (T)assertions.Subject;
                ((T)deserializedObject).Should().BeEquivalentTo(typedSubject, _ => options(defaultOptions));
            }
            catch (Exception exc)
            {
                Execute.Assertion
                .BecauseOf(because, becauseArgs)
                .FailWith("Expected {context:object} to be JSON serializable{reason}, but serializing {0} failed with {1}", assertions.Subject, exc);
            }

            return(new AndConstraint <ObjectAssertions>(assertions));
        }
        public static void AssemblyInitialize(TestContext context)
        {
            CurrentTestSettings = TestSettingProvider.GetSettings();
            DatabaseType        = TestSettingProvider.GetTestDatabaseType();

            if (DatabaseType.Equals("docker", StringComparison.OrdinalIgnoreCase))
            {
                // 取得 TestSettings 裡的 Docker 設定
                var containerSetting = TestSettingProvider.GetContainerSetting();
                var containerLabel   = CurrentTestSettings.ContainerLabel;

                CreateDockerContainer(containerSetting, containerLabel);
            }
            else
            {
                TestLocalDbProcess.CreateDatabase(TestDbConnections.LocalDb.Master, DatabaseName);
            }

            // FluentAssertions 設定 : 日期時間使用接近比對的方式,而非完全一致的比對
            AssertionOptions.AssertEquivalencyUsing(options =>
            {
                options.Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation))
                .WhenTypeIs <DateTime>();

                return(options);
            });
        }
示例#14
0
        public async Task <JsonResult> MakeAssertion([FromBody] AuthenticatorAssertionRawResponse clientResponse)
        {
            try
            {
                // 1. Get the assertion options we sent the client
                //var jsonOptions = HttpContext.Session.GetString("fido2.assertionOptions");
                var jsonOptions = await _distributedCache.GetStringAsync(UniqueId);

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

                // 2. Get registered credential from database
                var creds = await _fido2Storage.GetCredentialById(clientResponse.Id);

                if (creds == null)
                {
                    throw new Exception("Unknown credentials");
                }

                // 3. Get credential counter from database
                var storedCounter = creds.SignatureCounter;

                // 4. Create callback to check if userhandle owns the credentialId
                IsUserHandleOwnerOfCredentialIdAsync callback = async(args) =>
                {
                    var storedCreds = await _fido2Storage.GetCredentialsByUserHandleAsync(args.UserHandle);

                    return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId)));
                };

                // 5. Make the assertion
                var res = await _lib.MakeAssertionAsync(clientResponse, options, creds.PublicKey, storedCounter, callback);

                // 6. Store the updated counter
                await _fido2Storage.UpdateCounter(res.CredentialId, res.Counter);

                // complete sign-in
                var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();

                if (user == null)
                {
                    throw new InvalidOperationException($"Unable to load two-factor authentication user.");
                }

                var result = await _signInManager.TwoFactorSignInAsync("FIDO2", string.Empty, false, false);

                // 7. return OK to client
                return(Json(res));
            }
            catch (Exception e)
            {
                return(Json(new AssertionVerificationResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
示例#15
0
 /// <summary>
 /// Initializes an intance of <see cref="DefaultSettingsFixture"/>.
 /// </summary>
 public DefaultSettingsFixture()
 {
     // We need RespectingRuntimeTypes() to ensure equivalence test works property,
     // given that there are multiple types that can be used for the declared type OpenApiAny.
     // Without this option, properties specific to those types would not be compared.
     AssertionOptions.AssertEquivalencyUsing(
         o => o.AllowingInfiniteRecursion().RespectingRuntimeTypes());
 }
示例#16
0
 public SqlProcessingInformationServiceTests()
 {
     AssertionOptions.AssertEquivalencyUsing(options =>
     {
         options.Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTime>();
         options.Using <DateTimeOffset>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTimeOffset>();
         return(options);
     });
 }
示例#17
0
 public When_assertion_doubles_should_always_allow_small_deviations()
 {
     When(() =>
     {
         AssertionOptions.AssertEquivalencyUsing(options => options
                                                 .Using <double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, 0.01))
                                                 .WhenTypeIs <double>());
     });
 }
示例#18
0
            public void When_injecting_a_null_configurer_it_should_throw()
            {
                // Arrange
                Action act = () => AssertionOptions.AssertEquivalencyUsing(defaultsConfigurer: null);

                // Assert
                act.Should().ThrowExactly <ArgumentNullException>()
                .Which.ParamName.Should().Be("defaultsConfigurer");
            }
示例#19
0
 public static void ApproximationDateTime()
 {
     AssertionOptions.AssertEquivalencyUsing(options =>
     {
         options.Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTime>();
         options.Using <DateTimeOffset>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTimeOffset>();
         return(options);
     });
 }
示例#20
0
 public When_local_similar_options_are_used()
 {
     When(() =>
     {
         AssertionOptions.AssertEquivalencyUsing(options => options
                                                 .Using <double>(ctx => ctx.Subject.Should().BeApproximately(ctx.Expectation, 0.01))
                                                 .WhenTypeIs <double>());
     });
 }
示例#21
0
        public async Task <IActionResult> Fido2LoginCallback([FromBody] AuthenticatorAssertionRawResponse clientResponse, [FromHeader] string returnUrl)
        {
            var info = await HttpContext.AuthenticateAsync(_fido2AuthenticationScheme);

            var tempUser = info?.Principal;

            if (tempUser == null)
            {
                return(Json(new { success = false }));
            }
            var user = await _users.FindByIdAsync(tempUser.GetSubjectId());

            try
            {
                // 1. Get the assertion options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.assertionOptions");
                var options     = AssertionOptions.FromJson(jsonOptions);

                // 2. Get registered credential from database
                var creds = _authenticationContext.FidoLogins.FirstOrDefault(x => x.PublicKeyIdBytes.SequenceEqual(clientResponse.Id));
                //DemoStorage.GetCredentialById(clientResponse.Id);

                if (creds == null)
                {
                    throw new Exception("Unknown credentials");
                }

                if (creds.UserId != user.Id)
                {
                    throw new Exception("User is not owner of credentials.");
                }

                // 3. Get credential counter from database
                var storedCounter = creds.SignatureCounter;

                // 4. Create callback to check if userhandle owns the credentialId
                IsUserHandleOwnerOfCredentialIdAsync callback = async(args) =>
                {
                    return(_authenticationContext.FidoLogins.FirstOrDefault(x => x.UserHandle.SequenceEqual(args.UserHandle) && x.PublicKeyIdBytes.SequenceEqual(args.CredentialId)) != null);
                };

                // 5. Make the assertion
                var res = await _lib.MakeAssertionAsync(clientResponse, options, creds.PublicKey, storedCounter, callback);


                // 6. Store the updated counter
                creds.SignatureCounter = res.Counter;
                _authenticationContext.SaveChanges();

                // 7. return OK to client
                return(Json(new { success = true }));
            }
            catch (Exception e)
            {
                return(Json(new { success = false }));
            }
        }
示例#22
0
        public async Task <JsonResult> MakeAssertion([FromBody] AuthenticatorAssertionRawResponse clientResponse)
        {
            try
            {
                // 1. Get the assertion options we sent the client
                var jsonOptions = HttpContext.Session.GetString("fido2.assertionOptions");
                var options     = AssertionOptions.FromJson(jsonOptions);

                // 2. Get registered credential from database

                var signInUser = await _signInManager.GetTwoFactorAuthenticationUserAsync();

                var applicationUser = await _userManager.FindByNameAsync(signInUser.UserName);

                var creds = _fido2CredentialService.GetCredentialByUser(applicationUser);



                if (creds == null)
                {
                    throw new Exception("Unknown credentials");
                }

                // 3. Get credential counter from database
                var storedCounter = creds.SignatureCounter;

                // 4. Create callback to check if userhandle owns the credentialId
                IsUserHandleOwnerOfCredentialIdAsync callback = async(args) =>
                {
                    var storedCreds = await _fido2CredentialService.GetCredentialsByUserHandleAsync(args.UserHandle);

                    return(storedCreds.Exists(c => new PublicKeyCredentialDescriptor(c.Descriptor).Id.SequenceEqual(args.CredentialId)));
                };

                // 5. Make the assertion
                var res = await _fido2.MakeAssertionAsync(clientResponse, options, creds.PublicKey, storedCounter, callback);

                // 6. Store the updated counter
                var code = await _fido2CredentialService.UpdateCounter(res.CredentialId, res.Counter);

                // TODO Fix counter
                // TODO Allow more than one key to work

                // var result = await _signInManager.TwoFactorSignInAsync("Fido2", string.Empty, false, false);
                await _signInManager.SignInAsync(applicationUser, false);

                // 7. return OK to client
                return(Json(res));
            }
            catch (Exception e)
            {
                return(Json(new AssertionVerificationResult {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
示例#23
0
        public async Task TestFido2AssertionWithExistingU2fRegistrationWithAppId()
        {
            // u2f registration with appId
            var appId         = "https://localhost:44336";
            var keyHandleData = Base64Url.Decode("2uzGTqu9XGoDQpRBhkv3qDYWzEEZrDjOHT94fHe3J9VXl6KpaY6jL1C4gCAVSBCWZejOn-EYSyXfiG7RDQqgKw");
            var publicKeyData = Base64Url.Decode("BEKJkJiDzo8wlrYbAHmyz5a5vShbkStO58ZO7F-hy4fvBp6TowCZoV2dNGcxIN1yT18799bb_WuP0Yq_DSv5a-U");

            //key as cbor
            var publicKey = CreatePublicKeyFromU2fRegistrationData(keyHandleData, publicKeyData);

            var options = new AssertionOptions
            {
                Challenge        = Base64Url.Decode("mNxQVDWI8+ahBXeQJ8iS4jk5pDUd5KetZGVOwSkw2X0"),
                RpId             = "localhost",
                AllowCredentials = new[]
                {
                    new PublicKeyCredentialDescriptor
                    {
                        Id   = keyHandleData,
                        Type = PublicKeyCredentialType.PublicKey
                    }
                },
                Extensions = new AuthenticationExtensionsClientInputs
                {
                    AppID = appId
                }
            };

            var authResponse = new AuthenticatorAssertionRawResponse
            {
                Id         = keyHandleData,
                RawId      = keyHandleData,
                Type       = PublicKeyCredentialType.PublicKey,
                Extensions = new AuthenticationExtensionsClientOutputs
                {
                    AppID = true
                },
                Response = new AuthenticatorAssertionRawResponse.AssertionResponse
                {
                    AuthenticatorData = Base64Url.Decode("B6_fPoU4uitIYRHXuNfpbqt5mrDWz8cp7d1noAUrAucBAAABTQ"),
                    ClientDataJson    = Base64Url.Decode("eyJjaGFsbGVuZ2UiOiJtTnhRVkRXSTgtYWhCWGVRSjhpUzRqazVwRFVkNUtldFpHVk93U2t3MlgwIiwib3JpZ2luIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMzYiLCJ0eXBlIjoid2ViYXV0aG4uZ2V0In0"),
                    Signature         = Base64Url.Decode("MEQCICHV36RVY9DdFmKZgxF5Z_yScpPPsKcj__8KcPmngtGHAiAq_SzmTY8rZz4-5uNNiz3h6xO9osNTh7O7Mjqtoxul8w")
                }
            };

            IFido2 fido2 = new Fido2(new Fido2Configuration
            {
                Origins = new System.Collections.Generic.HashSet <string> {
                    "https://localhost:44336"
                }                                                                                      //data was generated with this origin
            });

            var res = await fido2.MakeAssertionAsync(authResponse, options, publicKey.Encode(), 0, null);

            Assert.Equal("ok", res.Status);
        }
示例#24
0
        public void Constructor_GiveValidArguments_PropertiesAreSet()
        {
            var authenticatorAssertionRawResponse = new AuthenticatorAssertionRawResponse();
            var assertionOptions = new AssertionOptions();
            var command          =
                new ValidateDeviceMfaAgainstCurrentUserCommand(authenticatorAssertionRawResponse, assertionOptions);

            Assert.Equal(authenticatorAssertionRawResponse, command.AuthenticatorAssertionRawResponse);
            Assert.Equal(assertionOptions, command.AssertionOptions);
        }
示例#25
0
        public void PartiallyAuthenticatedDeviceConstructor_GiveValidArguments_PropertiesAreSet()
        {
            var assertionOptions = new AssertionOptions();
            var commandResult    = new AuthenticateUserCommandResult(TestVariables.UserId, MfaProvider.Device, assertionOptions);

            Assert.Equal(TestVariables.UserId, commandResult.UserId);
            Assert.Equal(BaseAuthenticationProcessCommandResult.AuthenticationState.AwaitingMfaDeviceCode, commandResult.AuthenticationStatus);
            Assert.Equal(MfaProvider.Device, commandResult.SetupMfaProviders);
            Assert.Equal(assertionOptions, commandResult.AssertionOptions);
        }
        public async Task <CacheItem> ExecuteAsync(string fido2Payload, CacheItem relatedItem)
        {
            var request = OwnIdSerializer.Deserialize <Fido2LoginRequest>(fido2Payload);

            var storedFido2Info = await _userHandlerAdapter.FindFido2InfoAsync(request.CredentialId);

            if (storedFido2Info == null)
            {
                throw new OwnIdException(ErrorType.UserNotFound);
            }

            var options = new AssertionOptions
            {
                Challenge = Encoding.ASCII.GetBytes(relatedItem.Context),
                RpId      = _configuration.Fido2.RelyingPartyId
            };

            var fidoResponse = new AuthenticatorAssertionRawResponse
            {
                Extensions = new AuthenticationExtensionsClientOutputs(),
                Id         = Base64Url.Decode(request.CredentialId),
                RawId      = Base64Url.Decode(request.CredentialId),
                Response   = new AuthenticatorAssertionRawResponse.AssertionResponse
                {
                    AuthenticatorData = Base64Url.Decode(request.AuthenticatorData),
                    ClientDataJson    = Base64Url.Decode(request.ClientDataJson),
                    Signature         = Base64Url.Decode(request.Signature),
                    UserHandle        = Base64Url.Decode(storedFido2Info.UserId)
                },
                Type = PublicKeyCredentialType.PublicKey
            };

            var result = await _fido2.MakeAssertionAsync(
                fidoResponse,
                options,
                Base64Url.Decode(storedFido2Info.PublicKey),
                storedFido2Info.SignatureCounter,
                args =>
            {
                var storedCredentialId     = Base64Url.Decode(storedFido2Info.CredentialId);
                var storedCredDescriptor   = new PublicKeyCredentialDescriptor(storedCredentialId);
                var credIdValidationResult = storedCredDescriptor.Id.SequenceEqual(args.CredentialId);

                return(Task.FromResult(credIdValidationResult));
            });

            return(await _cacheItemRepository.UpdateAsync(relatedItem.Context, item =>
            {
                item.PublicKey = storedFido2Info.PublicKey;
                item.Fido2SignatureCounter = result.Counter;
                item.Fido2CredentialId = request.CredentialId;
                item.FinishFlow(storedFido2Info.UserId, storedFido2Info.PublicKey);
            }));
        }
示例#27
0
 public void RunBeforeAnyTests()
 {
     AssertionOptions.AssertEquivalencyUsing(options => options
                                             .IncludingNestedObjects()
                                             .IncludingInternalProperties()
                                             .IncludingInternalFields()
                                             .AllowingInfiniteRecursion()
                                             .RespectingRuntimeTypes()
                                             .WithTracing()
                                             .WithStrictOrdering());
 }
        public SqlScriptServiceTests()
        {
            var settings = new CommonDatabaseSettings();

            _database = new ScriptDatabase(settings);
            AssertionOptions.AssertEquivalencyUsing(options =>
            {
                options.Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTime>();
                options.Using <DateTimeOffset>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation)).WhenTypeIs <DateTimeOffset>();
                return(options);
            });
        }
示例#29
0
        protected KontoTestBase(ITestOutputHelper output) : base(output)
        {
            AssertionOptions.AssertEquivalencyUsing(o =>
            {
                o.Using <Transaktion>(t => t.Subject.ShouldBeEquivalentTo(t.Expectation,
                                                                          x => x.Excluding(p => p.Timestamp)))
                .WhenTypeIs <Transaktion>();
                return(o);
            });

            this.Konto = this.CreateKonto();
        }
示例#30
0
        // Only API call
        public async Task <AuthorizationResponse> SignInAsync(SecurityKeySignInModel parameters)
        {
            var assertionRawResponse = parameters.AuthenticatorAssertionRawResponse;

            // Get the assertion options we sent the client
            var jsonOptions = _memoryCache.Get <string>(Convert.ToBase64String(assertionRawResponse.Id));
            var options     = AssertionOptions.FromJson(jsonOptions);

            // Get registered credential from database
            var creds = await GetCredentialById(assertionRawResponse.Id);

            if (creds == null)
            {
                throw new Exception("Unknown credentials");
            }

            // Get credential counter from database
            var storedCounter = creds.SignatureCounter;

            // Create callback to check if userhandle owns the credentialId
            IsUserHandleOwnerOfCredentialIdAsync callback = async(args) =>
            {
                var storedCreds = await GetCredentialsByUserHandleAsync(args.UserHandle);

                return(storedCreds.Exists(c => c.Descriptor.Id.SequenceEqual(args.CredentialId)));
            };

            // Make the assertion
            var res = await _lib.MakeAssertionAsync(assertionRawResponse, options, creds.PublicKey, storedCounter, callback);

            // Store the updated counter
            await UpdateCounter(res.CredentialId, res.Counter);

            // Get authenticator flags
            var authData = new AuthenticatorData(assertionRawResponse.Response.AuthenticatorData);

            if (authData.UserPresent && authData.UserVerified)
            {
                var user = await _userManager.FindByNameAsync(creds.Username);

                if (user == null)
                {
                    throw new HESException(HESCode.UserNotFound);
                }

                await _signInManager.SignInAsync(user, parameters.RememberMe);

                return(AuthorizationResponse.Success(user));
            }

            return(AuthorizationResponse.Error(HESCode.AuthenticatorNotFIDO2));
        }