1
0
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:
Matt Gibson 2022-09-26 15:22:02 -04:00 committed by GitHub
parent 02bea3c48d
commit c8c9b32904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 255 additions and 57 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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>>>())
); );
} }
} }

View File

@ -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();

View File

@ -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; }
} }

View 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; }
}

View File

@ -0,0 +1,8 @@
using Serilog.Events;
namespace Bit.Core.Settings.LoggingSettings;
public class AdminLogLevelSettings : IAdminLogLevelSettings
{
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
}

View 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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,8 @@
using Serilog.Events;
namespace Bit.Core.Settings.LoggingSettings;
public class EventsProcessorLogLevelSettings : IEventsProcessorLogLevelSettings
{
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
}

View File

@ -0,0 +1,8 @@
using Serilog.Events;
namespace Bit.Core.Settings.LoggingSettings;
public class IconsLogLevelSettings : IIconsLogLevelSettings
{
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
}

View File

@ -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;
}

View 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();
}

View File

@ -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;
}

View File

@ -0,0 +1,8 @@
using Serilog.Events;
namespace Bit.Core.Settings.LoggingSettings;
public class ScimLogLevelSettings : IScimLogLevelSettings
{
public LogEventLevel Default { get; set; } = LogEventLevel.Warning;
}

View File

@ -0,0 +1,8 @@
using Serilog.Events;
namespace Bit.Core.Settings.LoggingSettings;
public class SsoLogLevelSettings : ISsoLogLevelSettings
{
public LogEventLevel Default { get; set; } = LogEventLevel.Error;
}

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);

View File

@ -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()

View File

@ -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();

View File

@ -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();

View File

@ -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;
})); }));
}); });
} }

View File

@ -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()

View File

@ -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)