mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 16:42:50 -05:00
Add logging to tokenables (#2298)
* Add logging to token usages * Add settings manipulation of log levels * Maintain no logging for dev * Log exception causing Token failure in TryUnprotect * dotnet format 🤖 * Added deconstruction operator on new debug logs. * Split off log level settings into separate files * Improve log messages * dotnet format 🤖 * Fix token serialization * Final review notes Co-authored-by: Todd Martin <>
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Bit.Core.Tokens;
|
||||
|
||||
@ -6,15 +7,17 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
||||
{
|
||||
private readonly IDataProtector _dataProtector;
|
||||
private readonly string _clearTextPrefix;
|
||||
private readonly ILogger<DataProtectorTokenFactory<T>> _logger;
|
||||
|
||||
public DataProtectorTokenFactory(string clearTextPrefix, string purpose, IDataProtectionProvider dataProtectionProvider)
|
||||
public DataProtectorTokenFactory(string clearTextPrefix, string purpose, IDataProtectionProvider dataProtectionProvider, ILogger<DataProtectorTokenFactory<T>> logger)
|
||||
{
|
||||
_dataProtector = dataProtectionProvider.CreateProtector(purpose);
|
||||
_clearTextPrefix = clearTextPrefix;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string Protect(T data) =>
|
||||
data.ToToken().ProtectWith(_dataProtector).WithPrefix(_clearTextPrefix).ToString();
|
||||
data.ToToken().ProtectWith(_dataProtector, _logger).WithPrefix(_clearTextPrefix).ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Unprotect token
|
||||
@ -24,7 +27,7 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
||||
/// <returns>The parsed tokenable</returns>
|
||||
/// <exception>Throws CryptographicException if fails to unprotect</exception>
|
||||
public T Unprotect(string token) =>
|
||||
Tokenable.FromToken<T>(new Token(token).RemovePrefix(_clearTextPrefix).UnprotectWith(_dataProtector).ToString());
|
||||
Tokenable.FromToken<T>(new Token(token).RemovePrefix(_clearTextPrefix).UnprotectWith(_dataProtector, _logger).ToString());
|
||||
|
||||
public bool TokenValid(string token)
|
||||
{
|
||||
@ -45,8 +48,9 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
||||
data = Unprotect(token);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogInformation(ex, "Failed to unprotect token: {rawToken}", token);
|
||||
data = default;
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Bit.Core.Tokens;
|
||||
|
||||
@ -26,11 +27,28 @@ public class Token
|
||||
return new Token(_token[expectedPrefix.Length..]);
|
||||
}
|
||||
|
||||
public Token ProtectWith(IDataProtector dataProtector) =>
|
||||
new(dataProtector.Protect(ToString()));
|
||||
|
||||
public Token UnprotectWith(IDataProtector dataProtector) =>
|
||||
new(dataProtector.Unprotect(ToString()));
|
||||
public Token ProtectWith(IDataProtector dataProtector, ILogger logger)
|
||||
{
|
||||
logger.LogDebug("Protecting token: {token}", this);
|
||||
return new(dataProtector.Protect(ToString()));
|
||||
}
|
||||
|
||||
public Token UnprotectWith(IDataProtector dataProtector, ILogger logger)
|
||||
{
|
||||
var unprotected = "";
|
||||
try
|
||||
{
|
||||
unprotected = dataProtector.Unprotect(ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogInformation(e, "Failed to unprotect token: {token}", this);
|
||||
throw;
|
||||
}
|
||||
logger.LogDebug("Unprotected token: {token} to {decryptedToken}", this, unprotected);
|
||||
return new(unprotected);
|
||||
}
|
||||
|
||||
public override string ToString() => _token;
|
||||
}
|
||||
|
Reference in New Issue
Block a user