mirror of
https://github.com/bitwarden/server.git
synced 2024-11-25 12:45:18 +01:00
Revert device id in jwt token and moved to reading from header. Added clear token by identifier API/repo/sproc so that token can be cleared after logout.
This commit is contained in:
parent
f07e9e9dd0
commit
da56901d17
@ -107,22 +107,12 @@ namespace Bit.Api.Controllers
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
[HttpPut("identifier/{identifier}/clear-token")]
|
[HttpPut("identifier/{identifier}/clear-token")]
|
||||||
[HttpPost("identifier/{identifier}/clear-token")]
|
[HttpPost("identifier/{identifier}/clear-token")]
|
||||||
public async Task<DeviceResponseModel> PutClearToken(string identifier)
|
public async Task PutClearToken(string identifier)
|
||||||
{
|
{
|
||||||
var device = await _deviceRepository.GetByIdentifierAsync(identifier, new Guid(_userManager.GetUserId(User)));
|
await _deviceRepository.ClearPushTokenByIdentifierAsync(identifier);
|
||||||
if(device == null)
|
|
||||||
{
|
|
||||||
await Task.Delay(2000);
|
|
||||||
throw new NotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
device.PushToken = null;
|
|
||||||
await _deviceService.SaveAsync(device);
|
|
||||||
|
|
||||||
var response = new DeviceResponseModel(device);
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
|
@ -9,7 +9,6 @@ using Microsoft.AspNetCore.Http.Authentication;
|
|||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Bit.Core.Domains;
|
using Bit.Core.Domains;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Core.Identity
|
namespace Bit.Core.Identity
|
||||||
{
|
{
|
||||||
@ -38,10 +37,9 @@ namespace Bit.Core.Identity
|
|||||||
// register the current context user
|
// register the current context user
|
||||||
var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>();
|
var currentContext = context.HttpContext.RequestServices.GetRequiredService<CurrentContext>();
|
||||||
currentContext.User = user;
|
currentContext.User = user;
|
||||||
var deviceIdentifierClaim = context.Ticket.Principal.Claims.SingleOrDefault(c => c.Type == "DeviceIdentifier");
|
if(context.HttpContext.Request.Headers.ContainsKey("Device-Identifier"))
|
||||||
if(deviceIdentifierClaim != null)
|
|
||||||
{
|
{
|
||||||
currentContext.DeviceIdentifier = deviceIdentifierClaim.Value;
|
currentContext.DeviceIdentifier = context.HttpContext.Request.Headers["Device-Identifier"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ namespace Bit.Core.Identity
|
|||||||
|
|
||||||
if(await UserManager.CheckPasswordAsync(user, password))
|
if(await UserManager.CheckPasswordAsync(user, password))
|
||||||
{
|
{
|
||||||
var result = await SignInOrTwoFactorAsync(user, device);
|
var result = await SignInOrTwoFactorAsync(user);
|
||||||
if(result.Succeeded && device != null)
|
if(result.Succeeded && device != null)
|
||||||
{
|
{
|
||||||
var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id);
|
var existingDevice = await _deviceRepository.GetByIdentifierAsync(device.Identifier, user.Id);
|
||||||
@ -105,7 +105,7 @@ namespace Bit.Core.Identity
|
|||||||
|
|
||||||
if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
|
if(await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
|
||||||
{
|
{
|
||||||
var token = await SignInAsync(user, false, device);
|
var token = await SignInAsync(user, false);
|
||||||
|
|
||||||
var success = JwtBearerSignInResult.Success;
|
var success = JwtBearerSignInResult.Success;
|
||||||
success.Token = token;
|
success.Token = token;
|
||||||
@ -127,7 +127,7 @@ namespace Bit.Core.Identity
|
|||||||
return JwtBearerSignInResult.Failed;
|
return JwtBearerSignInResult.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> SignInAsync(User user, bool twoFactor, Device device)
|
private async Task<string> SignInAsync(User user, bool twoFactor)
|
||||||
{
|
{
|
||||||
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
|
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
|
||||||
|
|
||||||
@ -150,11 +150,6 @@ namespace Bit.Core.Identity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(device != null && !string.IsNullOrWhiteSpace(device.Identifier))
|
|
||||||
{
|
|
||||||
userPrincipal.Identities.First().AddClaim(new Claim("DeviceIdentifier", device.Identifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
var descriptor = new SecurityTokenDescriptor
|
var descriptor = new SecurityTokenDescriptor
|
||||||
{
|
{
|
||||||
Issuer = JwtIdentityOptions.Issuer,
|
Issuer = JwtIdentityOptions.Issuer,
|
||||||
@ -169,13 +164,13 @@ namespace Bit.Core.Identity
|
|||||||
return handler.WriteToken(securityToken);
|
return handler.WriteToken(securityToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user, Device device)
|
private async Task<JwtBearerSignInResult> SignInOrTwoFactorAsync(User user)
|
||||||
{
|
{
|
||||||
if(UserManager.SupportsUserTwoFactor &&
|
if(UserManager.SupportsUserTwoFactor &&
|
||||||
await UserManager.GetTwoFactorEnabledAsync(user) &&
|
await UserManager.GetTwoFactorEnabledAsync(user) &&
|
||||||
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0)
|
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0)
|
||||||
{
|
{
|
||||||
var twoFactorToken = await SignInAsync(user, true, device);
|
var twoFactorToken = await SignInAsync(user, true);
|
||||||
|
|
||||||
var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired;
|
var twoFactorResult = JwtBearerSignInResult.TwoFactorRequired;
|
||||||
twoFactorResult.Token = twoFactorToken;
|
twoFactorResult.Token = twoFactorToken;
|
||||||
@ -184,7 +179,7 @@ namespace Bit.Core.Identity
|
|||||||
return twoFactorResult;
|
return twoFactorResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = await SignInAsync(user, false, device);
|
var token = await SignInAsync(user, false);
|
||||||
|
|
||||||
var result = JwtBearerSignInResult.Success;
|
var result = JwtBearerSignInResult.Success;
|
||||||
result.Token = token;
|
result.Token = token;
|
||||||
|
@ -10,5 +10,6 @@ namespace Bit.Core.Repositories
|
|||||||
Task<Device> GetByIdAsync(Guid id, Guid userId);
|
Task<Device> GetByIdAsync(Guid id, Guid userId);
|
||||||
Task<Device> GetByIdentifierAsync(string identifier, Guid userId);
|
Task<Device> GetByIdentifierAsync(string identifier, Guid userId);
|
||||||
Task<ICollection<Device>> GetManyByUserIdAsync(Guid userId);
|
Task<ICollection<Device>> GetManyByUserIdAsync(Guid userId);
|
||||||
|
Task ClearPushTokenByIdentifierAsync(string identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,5 +59,19 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
return results.ToList();
|
return results.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearPushTokenByIdentifierAsync(string identifier)
|
||||||
|
{
|
||||||
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
await connection.ExecuteAsync(
|
||||||
|
$"[{Schema}].[{Table}_ClearPushTokenByIdentifier]",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Identifier = identifier
|
||||||
|
},
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,5 +93,6 @@
|
|||||||
<Build Include="dbo\Stored Procedures\Device_ReadByIdentifierUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Device_ReadByIdentifierUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Cipher_ReadByUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Cipher_ReadByUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\User_UpdateEmailPassword.sql" />
|
<Build Include="dbo\Stored Procedures\User_UpdateEmailPassword.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\Device_ClearPushTokenByIdentifier.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -0,0 +1,13 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[Device_ClearPushTokenByIdentifier]
|
||||||
|
@Identifier NVARCHAR(50)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
UPDATE
|
||||||
|
[dbo].[Device]
|
||||||
|
SET
|
||||||
|
[Identifier] = NULL
|
||||||
|
WHERE
|
||||||
|
[Identifier] = @Identifier
|
||||||
|
END
|
Loading…
Reference in New Issue
Block a user