Example #1
0
 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();
 }
Example #2
0
        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);
            }
        }