mirror of
https://github.com/bitwarden/server.git
synced 2024-11-28 13:15:12 +01: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:
parent
02bea3c48d
commit
c8c9b32904
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Scim;
|
namespace Bit.Scim;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ public class Program
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Warning;
|
return e.Level >= globalSettings.MinLogLevel.ScimSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Sso;
|
namespace Bit.Sso;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (e.Properties.ContainsKey("RequestPath") &&
|
if (e.Properties.ContainsKey("RequestPath") &&
|
||||||
@ -24,7 +23,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.SsoSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Admin;
|
namespace Bit.Admin;
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ public class Program
|
|||||||
});
|
});
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (e.Properties.ContainsKey("RequestPath") &&
|
if (e.Properties.ContainsKey("RequestPath") &&
|
||||||
@ -27,7 +26,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.AdminSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Api;
|
namespace Bit.Api;
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (e.Exception != null &&
|
if (e.Exception != null &&
|
||||||
@ -26,19 +25,19 @@ public class Program
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Level == LogEventLevel.Information &&
|
if (
|
||||||
context.Contains(typeof(IpRateLimitMiddleware).FullName))
|
context.Contains(typeof(IpRateLimitMiddleware).FullName))
|
||||||
{
|
{
|
||||||
return true;
|
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IpRateLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level > LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.ApiSettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.ApiSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Billing;
|
namespace Bit.Billing;
|
||||||
|
|
||||||
@ -13,13 +12,12 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (e.Level == LogEventLevel.Information &&
|
if (context.StartsWith("\"Bit.Billing.Jobs") || context.StartsWith("\"Bit.Core.Jobs"))
|
||||||
(context.StartsWith("\"Bit.Billing.Jobs") || context.StartsWith("\"Bit.Core.Jobs")))
|
|
||||||
{
|
{
|
||||||
return true;
|
return e.Level >= globalSettings.MinLogLevel.BillingSettings.Jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Properties.ContainsKey("RequestPath") &&
|
if (e.Properties.ContainsKey("RequestPath") &&
|
||||||
@ -29,7 +27,7 @@ public class Program
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Warning;
|
return e.Level >= globalSettings.MinLogLevel.BillingSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -12,6 +12,7 @@ using Bit.Core.Settings;
|
|||||||
using Bit.Core.Tokens;
|
using Bit.Core.Tokens;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Bit.Core.OrganizationFeatures;
|
namespace Bit.Core.OrganizationFeatures;
|
||||||
|
|
||||||
@ -70,7 +71,8 @@ public static class OrganizationServiceCollectionExtensions
|
|||||||
new DataProtectorTokenFactory<OrganizationSponsorshipOfferTokenable>(
|
new DataProtectorTokenFactory<OrganizationSponsorshipOfferTokenable>(
|
||||||
OrganizationSponsorshipOfferTokenable.ClearTextPrefix,
|
OrganizationSponsorshipOfferTokenable.ClearTextPrefix,
|
||||||
OrganizationSponsorshipOfferTokenable.DataProtectorPurpose,
|
OrganizationSponsorshipOfferTokenable.DataProtectorPurpose,
|
||||||
serviceProvider.GetDataProtectionProvider())
|
serviceProvider.GetDataProtectionProvider(),
|
||||||
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<OrganizationSponsorshipOfferTokenable>>>())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Bit.Core.Settings;
|
using Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings;
|
||||||
|
|
||||||
public class GlobalSettings : IGlobalSettings
|
public class GlobalSettings : IGlobalSettings
|
||||||
{
|
{
|
||||||
@ -58,6 +60,7 @@ public class GlobalSettings : IGlobalSettings
|
|||||||
public virtual DocumentDbSettings DocumentDb { get; set; } = new DocumentDbSettings();
|
public virtual DocumentDbSettings DocumentDb { get; set; } = new DocumentDbSettings();
|
||||||
public virtual SentrySettings Sentry { get; set; } = new SentrySettings();
|
public virtual SentrySettings Sentry { get; set; } = new SentrySettings();
|
||||||
public virtual SyslogSettings Syslog { get; set; } = new SyslogSettings();
|
public virtual SyslogSettings Syslog { get; set; } = new SyslogSettings();
|
||||||
|
public virtual ILogLevelSettings MinLogLevel { get; set; } = new LogLevelSettings();
|
||||||
public virtual NotificationHubSettings NotificationHub { get; set; } = new NotificationHubSettings();
|
public virtual NotificationHubSettings NotificationHub { get; set; } = new NotificationHubSettings();
|
||||||
public virtual YubicoSettings Yubico { get; set; } = new YubicoSettings();
|
public virtual YubicoSettings Yubico { get; set; } = new YubicoSettings();
|
||||||
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
|
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
|
||||||
|
@ -15,5 +15,6 @@ public interface IGlobalSettings
|
|||||||
IBaseServiceUriSettings BaseServiceUri { get; set; }
|
IBaseServiceUriSettings BaseServiceUri { get; set; }
|
||||||
ITwoFactorAuthSettings TwoFactorAuth { get; set; }
|
ITwoFactorAuthSettings TwoFactorAuth { get; set; }
|
||||||
ISsoSettings Sso { get; set; }
|
ISsoSettings Sso { get; set; }
|
||||||
|
ILogLevelSettings MinLogLevel { get; set; }
|
||||||
IPasswordlessAuthSettings PasswordlessAuth { get; set; }
|
IPasswordlessAuthSettings PasswordlessAuth { get; set; }
|
||||||
}
|
}
|
||||||
|
74
src/Core/Settings/ILogLevelSettings.cs
Normal file
74
src/Core/Settings/ILogLevelSettings.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings;
|
||||||
|
|
||||||
|
public interface ILogLevelSettings
|
||||||
|
{
|
||||||
|
IBillingLogLevelSettings BillingSettings { get; set; }
|
||||||
|
IApiLogLevelSettings ApiSettings { get; set; }
|
||||||
|
IIdentityLogLevelSettings IdentitySettings { get; set; }
|
||||||
|
IScimLogLevelSettings ScimSettings { get; set; }
|
||||||
|
ISsoLogLevelSettings SsoSettings { get; set; }
|
||||||
|
IAdminLogLevelSettings AdminSettings { get; set; }
|
||||||
|
IEventsLogLevelSettings EventsSettings { get; set; }
|
||||||
|
IEventsProcessorLogLevelSettings EventsProcessorSettings { get; set; }
|
||||||
|
IIconsLogLevelSettings IconsSettings { get; set; }
|
||||||
|
INotificationsLogLevelSettings NotificationsSettings { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBillingLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
LogEventLevel Jobs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IApiLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
LogEventLevel IdentityToken { get; set; }
|
||||||
|
LogEventLevel IpRateLimit { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IIdentityLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
LogEventLevel IdentityToken { get; set; }
|
||||||
|
LogEventLevel IpRateLimit { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IScimLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISsoLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IAdminLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IEventsLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
LogEventLevel IdentityToken { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IEventsProcessorLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IIconsLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface INotificationsLogLevelSettings
|
||||||
|
{
|
||||||
|
LogEventLevel Default { get; set; }
|
||||||
|
LogEventLevel IdentityToken { get; set; }
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class AdminLogLevelSettings : IAdminLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
}
|
10
src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs
Normal file
10
src/Core/Settings/LoggingSettings/ApiLogLevelSettings.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class ApiLogLevelSettings : IApiLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
|
||||||
|
public LogEventLevel IpRateLimit { get; set; } = LogEventLevel.Information;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class BillingLogLevelSettings : IBillingLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
|
||||||
|
public LogEventLevel Jobs { get; set; } = LogEventLevel.Information;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class EventsLogLevelSettings : IEventsLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class EventsProcessorLogLevelSettings : IEventsProcessorLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class IconsLogLevelSettings : IIconsLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class IdentityLogLevelSettings : IIdentityLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
|
||||||
|
public LogEventLevel IpRateLimit { get; set; } = LogEventLevel.Information;
|
||||||
|
}
|
16
src/Core/Settings/LoggingSettings/LogLevelSettings.cs
Normal file
16
src/Core/Settings/LoggingSettings/LogLevelSettings.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class LogLevelSettings : ILogLevelSettings
|
||||||
|
{
|
||||||
|
public IBillingLogLevelSettings BillingSettings { get; set; } = new BillingLogLevelSettings();
|
||||||
|
public IApiLogLevelSettings ApiSettings { get; set; } = new ApiLogLevelSettings();
|
||||||
|
public IIdentityLogLevelSettings IdentitySettings { get; set; } = new IdentityLogLevelSettings();
|
||||||
|
public IScimLogLevelSettings ScimSettings { get; set; } = new ScimLogLevelSettings();
|
||||||
|
public ISsoLogLevelSettings SsoSettings { get; set; } = new SsoLogLevelSettings();
|
||||||
|
public IAdminLogLevelSettings AdminSettings { get; set; } = new AdminLogLevelSettings();
|
||||||
|
public IEventsLogLevelSettings EventsSettings { get; set; } = new EventsLogLevelSettings();
|
||||||
|
public IEventsProcessorLogLevelSettings EventsProcessorSettings { get; set; } = new EventsProcessorLogLevelSettings();
|
||||||
|
public IIconsLogLevelSettings IconsSettings { get; set; } = new IconsLogLevelSettings();
|
||||||
|
public INotificationsLogLevelSettings NotificationsSettings { get; set; } = new NotificationsLogLevelSettings();
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class NotificationsLogLevelSettings : INotificationsLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
|
||||||
|
public LogEventLevel IdentityToken { get; set; } = LogEventLevel.Fatal;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class ScimLogLevelSettings : IScimLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
|
||||||
|
}
|
8
src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs
Normal file
8
src/Core/Settings/LoggingSettings/SsoLogLevelSettings.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using Serilog.Events;
|
||||||
|
|
||||||
|
namespace Bit.Core.Settings.LoggingSettings;
|
||||||
|
|
||||||
|
public class SsoLogLevelSettings : ISsoLogLevelSettings
|
||||||
|
{
|
||||||
|
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Bit.Core.Tokens;
|
namespace Bit.Core.Tokens;
|
||||||
|
|
||||||
@ -6,15 +7,17 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
|||||||
{
|
{
|
||||||
private readonly IDataProtector _dataProtector;
|
private readonly IDataProtector _dataProtector;
|
||||||
private readonly string _clearTextPrefix;
|
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);
|
_dataProtector = dataProtectionProvider.CreateProtector(purpose);
|
||||||
_clearTextPrefix = clearTextPrefix;
|
_clearTextPrefix = clearTextPrefix;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Protect(T data) =>
|
public string Protect(T data) =>
|
||||||
data.ToToken().ProtectWith(_dataProtector).WithPrefix(_clearTextPrefix).ToString();
|
data.ToToken().ProtectWith(_dataProtector, _logger).WithPrefix(_clearTextPrefix).ToString();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unprotect token
|
/// Unprotect token
|
||||||
@ -24,7 +27,7 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
|||||||
/// <returns>The parsed tokenable</returns>
|
/// <returns>The parsed tokenable</returns>
|
||||||
/// <exception>Throws CryptographicException if fails to unprotect</exception>
|
/// <exception>Throws CryptographicException if fails to unprotect</exception>
|
||||||
public T Unprotect(string token) =>
|
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)
|
public bool TokenValid(string token)
|
||||||
{
|
{
|
||||||
@ -45,8 +48,9 @@ public class DataProtectorTokenFactory<T> : IDataProtectorTokenFactory<T> where
|
|||||||
data = Unprotect(token);
|
data = Unprotect(token);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation(ex, "Failed to unprotect token: {rawToken}", token);
|
||||||
data = default;
|
data = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Bit.Core.Tokens;
|
namespace Bit.Core.Tokens;
|
||||||
|
|
||||||
@ -26,11 +27,28 @@ public class Token
|
|||||||
return new Token(_token[expectedPrefix.Length..]);
|
return new Token(_token[expectedPrefix.Length..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Token ProtectWith(IDataProtector dataProtector) =>
|
|
||||||
new(dataProtector.Protect(ToString()));
|
|
||||||
|
|
||||||
public Token UnprotectWith(IDataProtector dataProtector) =>
|
public Token ProtectWith(IDataProtector dataProtector, ILogger logger)
|
||||||
new(dataProtector.Unprotect(ToString()));
|
{
|
||||||
|
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;
|
public override string ToString() => _token;
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,16 @@ public static class LoggerFactoryExtensions
|
|||||||
public static ILoggingBuilder AddSerilog(
|
public static ILoggingBuilder AddSerilog(
|
||||||
this ILoggingBuilder builder,
|
this ILoggingBuilder builder,
|
||||||
WebHostBuilderContext context,
|
WebHostBuilderContext context,
|
||||||
Func<LogEvent, bool> filter = null)
|
Func<LogEvent, IGlobalSettings, bool> filter = null)
|
||||||
{
|
{
|
||||||
if (context.HostingEnvironment.IsDevelopment())
|
if (context.HostingEnvironment.IsDevelopment())
|
||||||
{
|
{
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var globalSettings = new GlobalSettings();
|
||||||
|
ConfigurationBinder.Bind(context.Configuration.GetSection("GlobalSettings"), globalSettings);
|
||||||
|
|
||||||
bool inclusionPredicate(LogEvent e)
|
bool inclusionPredicate(LogEvent e)
|
||||||
{
|
{
|
||||||
if (filter == null)
|
if (filter == null)
|
||||||
@ -49,12 +52,9 @@ public static class LoggerFactoryExtensions
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return filter(e);
|
return filter(e, globalSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
var globalSettings = new GlobalSettings();
|
|
||||||
ConfigurationBinder.Bind(context.Configuration.GetSection("GlobalSettings"), globalSettings);
|
|
||||||
|
|
||||||
var config = new LoggerConfiguration()
|
var config = new LoggerConfiguration()
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.Filter.ByIncludingOnly(inclusionPredicate);
|
.Filter.ByIncludingOnly(inclusionPredicate);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Events;
|
namespace Bit.Events;
|
||||||
|
|
||||||
@ -14,13 +13,13 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level > LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.EventsSettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Properties.ContainsKey("RequestPath") &&
|
if (e.Properties.ContainsKey("RequestPath") &&
|
||||||
@ -30,7 +29,7 @@ public class Program
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.EventsSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.EventsProcessor;
|
namespace Bit.EventsProcessor;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e => e.Level >= LogEventLevel.Warning));
|
logging.AddSerilog(hostingContext, (e, globalSettings) => e.Level >= globalSettings.MinLogLevel.EventsProcessorSettings.Default));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
.Run();
|
.Run();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Icons;
|
namespace Bit.Icons;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e => e.Level >= LogEventLevel.Error));
|
logging.AddSerilog(hostingContext, (e, globalSettings) => e.Level >= globalSettings.MinLogLevel.IconsSettings.Default));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
.Run();
|
.Run();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Bit.Identity;
|
namespace Bit.Identity;
|
||||||
|
|
||||||
@ -22,22 +21,21 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (context.Contains(typeof(IpRateLimitMiddleware).FullName) &&
|
if (context.Contains(typeof(IpRateLimitMiddleware).FullName))
|
||||||
e.Level == LogEventLevel.Information)
|
|
||||||
{
|
{
|
||||||
return true;
|
return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IpRateLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level > LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.IdentitySettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.IdentitySettings.Default;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,13 @@ public class Program
|
|||||||
{
|
{
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
webBuilder.ConfigureLogging((hostingContext, logging) =>
|
||||||
logging.AddSerilog(hostingContext, e =>
|
logging.AddSerilog(hostingContext, (e, globalSettings) =>
|
||||||
{
|
{
|
||||||
var context = e.Properties["SourceContext"].ToString();
|
var context = e.Properties["SourceContext"].ToString();
|
||||||
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
if (context.Contains("IdentityServer4.Validation.TokenValidator") ||
|
||||||
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
|
||||||
{
|
{
|
||||||
return e.Level > LogEventLevel.Error;
|
return e.Level >= globalSettings.MinLogLevel.NotificationsSettings.IdentityToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Level == LogEventLevel.Error &&
|
if (e.Level == LogEventLevel.Error &&
|
||||||
@ -41,7 +41,7 @@ public class Program
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Level >= LogEventLevel.Warning;
|
return e.Level >= globalSettings.MinLogLevel.NotificationsSettings.Default;
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.Build()
|
.Build()
|
||||||
|
@ -35,6 +35,7 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Serilog.Context;
|
using Serilog.Context;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
@ -116,19 +117,22 @@ public static class ServiceCollectionExtensions
|
|||||||
new DataProtectorTokenFactory<EmergencyAccessInviteTokenable>(
|
new DataProtectorTokenFactory<EmergencyAccessInviteTokenable>(
|
||||||
EmergencyAccessInviteTokenable.ClearTextPrefix,
|
EmergencyAccessInviteTokenable.ClearTextPrefix,
|
||||||
EmergencyAccessInviteTokenable.DataProtectorPurpose,
|
EmergencyAccessInviteTokenable.DataProtectorPurpose,
|
||||||
serviceProvider.GetDataProtectionProvider())
|
serviceProvider.GetDataProtectionProvider(),
|
||||||
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<EmergencyAccessInviteTokenable>>>())
|
||||||
);
|
);
|
||||||
services.AddSingleton<IDataProtectorTokenFactory<HCaptchaTokenable>>(serviceProvider =>
|
services.AddSingleton<IDataProtectorTokenFactory<HCaptchaTokenable>>(serviceProvider =>
|
||||||
new DataProtectorTokenFactory<HCaptchaTokenable>(
|
new DataProtectorTokenFactory<HCaptchaTokenable>(
|
||||||
HCaptchaTokenable.ClearTextPrefix,
|
HCaptchaTokenable.ClearTextPrefix,
|
||||||
HCaptchaTokenable.DataProtectorPurpose,
|
HCaptchaTokenable.DataProtectorPurpose,
|
||||||
serviceProvider.GetDataProtectionProvider())
|
serviceProvider.GetDataProtectionProvider(),
|
||||||
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<HCaptchaTokenable>>>())
|
||||||
);
|
);
|
||||||
services.AddSingleton<IDataProtectorTokenFactory<SsoTokenable>>(serviceProvider =>
|
services.AddSingleton<IDataProtectorTokenFactory<SsoTokenable>>(serviceProvider =>
|
||||||
new DataProtectorTokenFactory<SsoTokenable>(
|
new DataProtectorTokenFactory<SsoTokenable>(
|
||||||
SsoTokenable.ClearTextPrefix,
|
SsoTokenable.ClearTextPrefix,
|
||||||
SsoTokenable.DataProtectorPurpose,
|
SsoTokenable.DataProtectorPurpose,
|
||||||
serviceProvider.GetDataProtectionProvider()));
|
serviceProvider.GetDataProtectionProvider(),
|
||||||
|
serviceProvider.GetRequiredService<ILogger<DataProtectorTokenFactory<SsoTokenable>>>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddDefaultServices(this IServiceCollection services, GlobalSettings globalSettings)
|
public static void AddDefaultServices(this IServiceCollection services, GlobalSettings globalSettings)
|
||||||
|
Loading…
Reference in New Issue
Block a user