public async Task<CompleteRegistrationResponse> Generate(CompleteRegistrationRequestValidationResult validationResult) { var device = validationResult.Device ?? new UserDevice(Guid.NewGuid()) { DateCreated = SystemClock.UtcNow, DeviceId = validationResult.DeviceId, Name = validationResult.DeviceName, Platform = validationResult.DevicePlatform, IsPushNotificationsEnabled = false, PublicKey = validationResult.PublicKey, UserId = validationResult.UserId }; switch (validationResult.InteractionMode) { case InteractionMode.Pin when validationResult.Device == null: var password = DevicePasswordHasher.HashPassword(device, validationResult.Pin); device.Password = password; await UserDeviceStore.CreateDevice(device); break; case InteractionMode.Pin when validationResult.Device != null: password = DevicePasswordHasher.HashPassword(device, validationResult.Pin); await UserDeviceStore.UpdateDevicePassword(device, password); break; case InteractionMode.Fingerprint when validationResult.Device == null: device.PublicKey = validationResult.PublicKey; await UserDeviceStore.CreateDevice(device); break; case InteractionMode.Fingerprint when validationResult.Device != null: await UserDeviceStore.UpdateDevicePublicKey(device, validationResult.PublicKey); break; } return new CompleteRegistrationResponse(); }
public async Task ValidateAsync(ExtensionGrantValidationContext context) { var parameters = context.Request.Raw; var deviceId = parameters.Get(RegistrationRequestParameters.DeviceId); if (string.IsNullOrWhiteSpace(deviceId)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, $"Parameter '{RegistrationRequestParameters.DeviceId}' is not specified."); return; } // Load device. var device = await UserDeviceStore.GetByDeviceId(deviceId); if (device == null) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Device is unknown."); return; } // If a code is present we are heading towards fingerprint login. var code = parameters.Get(RegistrationRequestParameters.Code); if (!string.IsNullOrWhiteSpace(code)) { // Retrieve authorization code from the store. var authorizationCode = await CodeChallengeStore.GetAuthorizationCode(code); if (authorizationCode == null) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Authorization code is invalid."); return; } // Validate that the consumer specified all required parameters. var parametersToValidate = new List <string> { RegistrationRequestParameters.CodeSignature, RegistrationRequestParameters.CodeVerifier }; foreach (var parameter in parametersToValidate) { var parameterValue = parameters.Get(parameter); if (string.IsNullOrWhiteSpace(parameterValue)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, $"Parameter '{parameter}' is not specified."); return; } } // Validate authorization code against code verifier given by the client. var codeVerifier = parameters.Get(RegistrationRequestParameters.CodeVerifier); var authorizationCodeValidationResult = await ValidateAuthorizationCode(code, authorizationCode, codeVerifier, deviceId, context.Request.Client); if (authorizationCodeValidationResult.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, authorizationCodeValidationResult.ErrorDescription); return; } // Validate given public key against signature for fingerprint. var publicKey = parameters.Get(RegistrationRequestParameters.PublicKey); var codeSignature = parameters.Get(RegistrationRequestParameters.CodeSignature); var publicKeyValidationResult = ValidateSignature(publicKey, code, codeSignature); if (publicKeyValidationResult.IsError) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, publicKeyValidationResult.ErrorDescription); return; } await UserDeviceStore.UpdateDevicePublicKey(device, publicKey); // Grant access token. context.Result = new GrantValidationResult(authorizationCode.Subject.GetSubjectId(), GrantType); await UserDeviceStore.UpdateLastSignInDate(device); } var pin = parameters.Get(RegistrationRequestParameters.Pin); if (!string.IsNullOrWhiteSpace(pin)) { var result = DevicePasswordHasher.VerifyHashedPassword(device, device.Password, pin); if (result == PasswordVerificationResult.Failed) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Wrong pin."); return; } context.Result = new GrantValidationResult(device.UserId, GrantType); await UserDeviceStore.UpdateLastSignInDate(device); } }