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

Add support for Key Connector OTP and account migration (#1663)

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
This commit is contained in:
Oscar Hinton
2021-11-09 16:37:32 +01:00
committed by GitHub
parent f6bc35b2d0
commit fd37cb5a12
62 changed files with 3799 additions and 306 deletions

View File

@ -176,7 +176,7 @@ namespace Bit.Core.IdentityServer
customResponse.Add("TwoFactorToken", token);
}
SetSuccessResult(context, user, claims, customResponse);
await SetSuccessResult(context, user, claims, customResponse);
}
protected async Task BuildTwoFactorResultAsync(User user, Organization organization, T context)
@ -256,7 +256,7 @@ namespace Bit.Core.IdentityServer
protected abstract void SetSsoResult(T context, Dictionary<string, object> customResponse);
protected abstract void SetSuccessResult(T context, User user, List<Claim> claims,
protected abstract Task SetSuccessResult(T context, User user, List<Claim> claims,
Dictionary<string, object> customResponse);
protected abstract void SetErrorResult(T context, Dictionary<string, object> customResponse);

View File

@ -24,6 +24,7 @@ namespace Bit.Core.IdentityServer
{
private UserManager<User> _userManager;
private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IOrganizationRepository _organizationRepository;
public CustomTokenRequestValidator(
UserManager<User> userManager,
@ -47,6 +48,7 @@ namespace Bit.Core.IdentityServer
{
_userManager = userManager;
_ssoConfigRepository = ssoConfigRepository;
_organizationRepository = organizationRepository;
}
public async Task ValidateAsync(CustomTokenRequestValidationContext context)
@ -58,25 +60,6 @@ namespace Bit.Core.IdentityServer
return;
}
await ValidateAsync(context, context.Result.ValidatedRequest);
if (context.Result.CustomResponse != null)
{
var organizationClaim = context.Result.ValidatedRequest.Subject?.FindFirst(c => c.Type == "organizationId");
var organizationId = organizationClaim?.Value ?? "";
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(new Guid(organizationId));
var ssoConfigData = ssoConfig.GetData();
if (ssoConfigData is { UseCryptoAgent: true } && !string.IsNullOrEmpty(ssoConfigData.CryptoAgentUrl))
{
context.Result.CustomResponse["CryptoAgentUrl"] = ssoConfigData.CryptoAgentUrl;
// Prevent clients redirecting to set-password
// TODO: Figure out if we can move this logic to the clients since this might break older clients
// although we will have issues either way with some clients supporting crypto anent and some not
// suggestion: We should roll out the clients before enabling it server wise
context.Result.CustomResponse["ResetMasterPassword"] = false;
}
}
}
protected async override Task<(User, bool)> ValidateContextAsync(CustomTokenRequestValidationContext context)
@ -87,7 +70,7 @@ namespace Bit.Core.IdentityServer
return (user, user != null);
}
protected override void SetSuccessResult(CustomTokenRequestValidationContext context, User user,
protected override async Task SetSuccessResult(CustomTokenRequestValidationContext context, User user,
List<Claim> claims, Dictionary<string, object> customResponse)
{
context.Result.CustomResponse = customResponse;
@ -100,6 +83,40 @@ namespace Bit.Core.IdentityServer
context.Result.ValidatedRequest.ClientClaims.Add(claim);
}
}
if (context.Result.CustomResponse == null || user.MasterPassword != null)
{
return;
}
// KeyConnector responses below
// Apikey login
if (context.Result.ValidatedRequest.GrantType == "client_credentials")
{
if (user.UsesKeyConnector) {
// KeyConnectorUrl is configured in the CLI client, just disable master password reset
context.Result.CustomResponse["ResetMasterPassword"] = false;
}
return;
}
// SSO login
var organizationClaim = context.Result.ValidatedRequest.Subject?.FindFirst(c => c.Type == "organizationId");
if (organizationClaim?.Value != null)
{
var organizationId = new Guid(organizationClaim.Value);
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organizationId);
var ssoConfigData = ssoConfig.GetData();
if (ssoConfigData is { UseKeyConnector: true } && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl))
{
context.Result.CustomResponse["KeyConnectorUrl"] = ssoConfigData.KeyConnectorUrl;
// Prevent clients redirecting to set-password
context.Result.CustomResponse["ResetMasterPassword"] = false;
}
}
}
protected override void SetTwoFactorResult(CustomTokenRequestValidationContext context,

View File

@ -106,13 +106,14 @@ namespace Bit.Core.IdentityServer
return (user, true);
}
protected override void SetSuccessResult(ResourceOwnerPasswordValidationContext context, User user,
protected override Task SetSuccessResult(ResourceOwnerPasswordValidationContext context, User user,
List<Claim> claims, Dictionary<string, object> customResponse)
{
context.Result = new GrantValidationResult(user.Id.ToString(), "Application",
identityProvider: "bitwarden",
claims: claims.Count > 0 ? claims : null,
customResponse: customResponse);
return Task.CompletedTask;
}
protected override void SetTwoFactorResult(ResourceOwnerPasswordValidationContext context,