1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-22 12:04:27 -05:00

verify all 2fa methods

This commit is contained in:
Kyle Spearrin 2017-06-20 14:50:12 -04:00
parent 69de88cc32
commit c13ba70ab4

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Services; using Bit.Core.Services;
using System.Linq;
namespace Bit.Core.IdentityServer namespace Bit.Core.IdentityServer
{ {
@ -18,15 +19,18 @@ namespace Bit.Core.IdentityServer
private UserManager<User> _userManager; private UserManager<User> _userManager;
private readonly IDeviceRepository _deviceRepository; private readonly IDeviceRepository _deviceRepository;
private readonly IDeviceService _deviceService; private readonly IDeviceService _deviceService;
private readonly IUserService _userService;
public ResourceOwnerPasswordValidator( public ResourceOwnerPasswordValidator(
UserManager<User> userManager, UserManager<User> userManager,
IDeviceRepository deviceRepository, IDeviceRepository deviceRepository,
IDeviceService deviceService) IDeviceService deviceService,
IUserService userService)
{ {
_userManager = userManager; _userManager = userManager;
_deviceRepository = deviceRepository; _deviceRepository = deviceRepository;
_deviceService = deviceService; _deviceService = deviceService;
_userService = userService;
} }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
@ -55,8 +59,7 @@ namespace Bit.Core.IdentityServer
return; return;
} }
if(!twoFactorRequest || if(!twoFactorRequest || await VerifyTwoFactor(user, twoFactorProviderType, twoFactorToken))
await _userManager.VerifyTwoFactorTokenAsync(user, twoFactorProviderType.ToString(), twoFactorToken))
{ {
var device = await SaveDeviceAsync(user, context); var device = await SaveDeviceAsync(user, context);
BuildSuccessResult(user, context, device); BuildSuccessResult(user, context, device);
@ -98,17 +101,19 @@ namespace Bit.Core.IdentityServer
private void BuildTwoFactorResult(User user, ResourceOwnerPasswordValidationContext context) private void BuildTwoFactorResult(User user, ResourceOwnerPasswordValidationContext context)
{ {
var providers = new List<byte>(); var providerKeys = new List<byte>();
if(user.TwoFactorProvider.HasValue) var providers = new Dictionary<byte, Dictionary<string, object>>();
foreach(var provider in user.GetTwoFactorProviders().Where(p => p.Value.Enabled))
{ {
providers.Add((byte)user.TwoFactorProvider.Value); providerKeys.Add((byte)provider.Key);
providers.Add((byte)provider.Key, null);
} }
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.", context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.",
new Dictionary<string, object> new Dictionary<string, object>
{ {
{ "TwoFactorProviders", providers }, { "TwoFactorProviders", providers.Keys },
{ "TwoFactorProvider", (byte)user.TwoFactorProvider.Value } { "TwoFactorProviders2", providers }
}); });
} }
@ -152,6 +157,22 @@ namespace Bit.Core.IdentityServer
}; };
} }
private async Task<bool> VerifyTwoFactor(User user, TwoFactorProviderType type, string token)
{
switch(type)
{
case TwoFactorProviderType.Authenticator:
case TwoFactorProviderType.Duo:
case TwoFactorProviderType.YubiKey:
case TwoFactorProviderType.U2F:
return await _userManager.VerifyTwoFactorTokenAsync(user, type.ToString(), token);
case TwoFactorProviderType.Email:
return await _userService.VerifyTwoFactorEmailAsync(user, token);
default:
return false;
}
}
private async Task<Device> SaveDeviceAsync(User user, ResourceOwnerPasswordValidationContext context) private async Task<Device> SaveDeviceAsync(User user, ResourceOwnerPasswordValidationContext context)
{ {
var device = GetDeviceFromRequest(context); var device = GetDeviceFromRequest(context);