1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-21 21:15:10 -05:00

two factor params on login

This commit is contained in:
Kyle Spearrin 2017-06-21 12:13:18 -04:00
parent 7095ae0ea1
commit 2ce47edadf

View File

@ -11,6 +11,7 @@ using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Services; using Bit.Core.Services;
using System.Linq; using System.Linq;
using Bit.Core.Models;
namespace Bit.Core.IdentityServer namespace Bit.Core.IdentityServer
{ {
@ -49,13 +50,13 @@ namespace Bit.Core.IdentityServer
TwoFactorProviderType twoFactorProviderType = TwoFactorProviderType.Authenticator; // Just defaulting it TwoFactorProviderType twoFactorProviderType = TwoFactorProviderType.Authenticator; // Just defaulting it
if(!twoFactorRequest && await TwoFactorRequiredAsync(user)) if(!twoFactorRequest && await TwoFactorRequiredAsync(user))
{ {
BuildTwoFactorResult(user, context); await BuildTwoFactorResultAsync(user, context);
return; return;
} }
if(twoFactorRequest && !Enum.TryParse(twoFactorProvider, out twoFactorProviderType)) if(twoFactorRequest && !Enum.TryParse(twoFactorProvider, out twoFactorProviderType))
{ {
BuildTwoFactorResult(user, context); await BuildTwoFactorResultAsync(user, context);
return; return;
} }
@ -99,14 +100,15 @@ namespace Bit.Core.IdentityServer
customResponse: customResponse); customResponse: customResponse);
} }
private void BuildTwoFactorResult(User user, ResourceOwnerPasswordValidationContext context) private async Task BuildTwoFactorResultAsync(User user, ResourceOwnerPasswordValidationContext context)
{ {
var providerKeys = new List<byte>(); var providerKeys = new List<byte>();
var providers = new Dictionary<byte, Dictionary<string, object>>(); var providers = new Dictionary<byte, Dictionary<string, object>>();
foreach(var provider in user.GetTwoFactorProviders().Where(p => p.Value.Enabled)) foreach(var provider in user.GetTwoFactorProviders().Where(p => p.Value.Enabled))
{ {
providerKeys.Add((byte)provider.Key); providerKeys.Add((byte)provider.Key);
providers.Add((byte)provider.Key, null); var infoDict = await BuildTwoFactorParams(user, provider.Key, provider.Value);
providers.Add((byte)provider.Key, infoDict);
} }
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.", context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Two factor required.",
@ -173,6 +175,33 @@ namespace Bit.Core.IdentityServer
} }
} }
private async Task<Dictionary<string, object>> BuildTwoFactorParams(User user, TwoFactorProviderType type,
TwoFactorProvider provider)
{
switch(type)
{
case TwoFactorProviderType.Duo:
case TwoFactorProviderType.U2F:
var token = await _userManager.GenerateTwoFactorTokenAsync(user, type.ToString());
if(type == TwoFactorProviderType.Duo)
{
return new Dictionary<string, object>
{
["Host"] = provider.MetaData["Host"],
["Signature"] = token
};
}
else if(type == TwoFactorProviderType.U2F)
{
// TODO: U2F challenge
return new Dictionary<string, object> { };
}
return null;
default:
return null;
}
}
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);