Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add log event name for Identity #16879

Merged
merged 4 commits into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -48,7 +48,7 @@ internal IEnumerable<ApiResource> GetApiResources()
{
foreach (var kvp in data)
{
_logger.LogInformation($"Configuring API resource '{kvp.Key}'.");
_logger.LogInformation(LoggerEventIds.ConfiguringAPIResource, "Configuring API resource '{ApiResourceName}'.", kvp.Key);
yield return GetResource(kvp.Key, kvp.Value);
}
}
Expand All @@ -58,7 +58,7 @@ internal IEnumerable<ApiResource> GetApiResources()
{
foreach (var kvp in localResources)
{
_logger.LogInformation($"Configuring local API resource '{kvp.Key}'.");
_logger.LogInformation(LoggerEventIds.ConfiguringLocalAPIResource, "Configuring local API resource '{ApiResourceName}'.", kvp.Key);
yield return GetResource(kvp.Key, kvp.Value);
}
}
Expand Down Expand Up @@ -107,4 +107,4 @@ private ApiResource GetLocalAPI(string name, ResourceDefinition definition) =>
.ReplaceScopes(ParseScopes(definition.Scopes) ?? new[] { name })
.Build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,24 @@ private void AddIdentityResourceScopesToClients(ApiAuthorizationOptions options)
{
if (!identityResource.Properties.TryGetValue(ApplicationProfilesPropertyNames.Clients, out var clientList))
{
_logger.LogInformation($"Identity resource '{identityResource.Name}' doesn't define a list of allowed applications.");
_logger.LogInformation(LoggerEventIds.AllowedApplicationNotDefienedForIdentityResource, "Identity resource '{IdentityResourceName}' doesn't define a list of allowed applications.", identityResource.Name);
continue;
}

var resourceClients = clientList.Split(DefaultClientListSeparator, StringSplitOptions.RemoveEmptyEntries);
if (resourceClients.Length == 0)
{
_logger.LogInformation($"Identity resource '{identityResource.Name}' doesn't define a list of allowed applications.");
_logger.LogInformation(LoggerEventIds.AllowedApplicationNotDefienedForIdentityResource, "Identity resource '{IdentityResourceName}' doesn't define a list of allowed applications.", identityResource.Name);
continue;
}

if (resourceClients.Length == 1 && resourceClients[0] == ApplicationProfilesPropertyValues.AllowAllApplications)
{
_logger.LogInformation($"Identity resource '{identityResource.Name}' allows all applications.");
_logger.LogInformation(LoggerEventIds.AllApplicationsAllowedForIdentityResource, "Identity resource '{IdentityResourceName}' allows all applications.", identityResource.Name);
}
else
{
_logger.LogInformation($"Identity resource '{identityResource.Name}' allows applications '{string.Join(" ", resourceClients)}'.");
_logger.LogInformation(LoggerEventIds.ApplicationsAllowedForIdentityResource, "Identity resource '{IdentityResourceName}' allows applications '{ResourceClients}'.", identityResource.Name, string.Join(" ", resourceClients));
}

foreach (var client in options.Clients)
Expand All @@ -68,24 +68,24 @@ private void AddApiResourceScopesToClients(ApiAuthorizationOptions options)
{
if (!resource.Properties.TryGetValue(ApplicationProfilesPropertyNames.Clients, out var clientList))
{
_logger.LogInformation($"Resource '{resource.Name}' doesn't define a list of allowed applications.");
_logger.LogInformation(LoggerEventIds.AllowedApplicationNotDefienedForApiResource, "Resource '{ApiResourceName}' doesn't define a list of allowed applications.", resource.Name);
continue;
}

var resourceClients = clientList.Split(DefaultClientListSeparator, StringSplitOptions.RemoveEmptyEntries);
if (resourceClients.Length == 0)
{
_logger.LogInformation($"Resource '{resource.Name}' doesn't define a list of allowed applications.");
_logger.LogInformation(LoggerEventIds.AllowedApplicationNotDefienedForApiResource, "Resource '{ApiResourceName}' doesn't define a list of allowed applications.", resource.Name);
continue;
}

if (resourceClients.Length == 1 && resourceClients[0] == ApplicationProfilesPropertyValues.AllowAllApplications)
{
_logger.LogInformation($"Resource '{resource.Name}' allows all applications.");
_logger.LogInformation(LoggerEventIds.AllApplicationsAllowedForApiResource, "Resource '{ApiResourceName}' allows all applications.", resource.Name);
}
else
{
_logger.LogInformation($"Resource '{resource.Name}' allows applications '{string.Join(" ", resourceClients)}'.");
_logger.LogInformation(LoggerEventIds.ApplicationsAllowedForApiResource, "Resource '{ApiResourceName}' allows applications '{resourceClients}'.", resource.Name, string.Join(" ", resourceClients));
}

foreach (var client in options.Clients)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal IEnumerable<Client> GetClients()
{
foreach (var kvp in data)
{
_logger.LogInformation($"Configuring client '{kvp.Key}'.");
_logger.LogInformation(LoggerEventIds.ConfiguringClient, "Configuring client '{ClientName}'.", kvp.Key);
var name = kvp.Key;
var definition = kvp.Value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,23 @@ public SigningCredentials LoadKey()
case KeySources.Development:
var developmentKeyPath = Path.Combine(Directory.GetCurrentDirectory(), key.FilePath ?? DefaultTempKeyRelativePath);
var createIfMissing = key.Persisted ?? true;
_logger.LogInformation($"Loading development key at '{developmentKeyPath}'.");
_logger.LogInformation(LoggerEventIds.DevelopmentKeyLoaded, "Loading development key at '{developmentKeyPath}'.", developmentKeyPath);
var developmentKey = new RsaSecurityKey(SigningKeysLoader.LoadDevelopment(developmentKeyPath, createIfMissing))
{
KeyId = "Development"
};
return new SigningCredentials(developmentKey, "RS256");
case KeySources.File:
var pfxPath = Path.Combine(Directory.GetCurrentDirectory(), key.FilePath);
var pfxPassword = key.Password;
var storageFlags = GetStorageFlags(key);
_logger.LogInformation($"Loading certificate file at '{pfxPath}' with storage flags '{key.StorageFlags}'.");
_logger.LogInformation(LoggerEventIds.CertificateLoadedFromFile, "Loading certificate file at '{CertificatePath}' with storage flags '{CertificateStorageFlags}'.", pfxPath, key.StorageFlags);
return new SigningCredentials(new X509SecurityKey(SigningKeysLoader.LoadFromFile(pfxPath, key.Password, storageFlags)), "RS256");
case KeySources.Store:
if (!Enum.TryParse<StoreLocation>(key.StoreLocation, out var storeLocation))
{
throw new InvalidOperationException($"Invalid certificate store location '{key.StoreLocation}'.");
}
_logger.LogInformation($"Loading certificate with subject '{key.Name}' in '{key.StoreLocation}\\{key.StoreName}'.");
_logger.LogInformation(LoggerEventIds.CertificateLoadedFromStore, "Loading certificate with subject '{CertificateSubject}' in '{CertificateStoreLocation}\\{CertificateStoreName}'.", key.Name, key.StoreLocation, key.StoreName);
return new SigningCredentials(new X509SecurityKey(SigningKeysLoader.LoadFromStoreCert(key.Name, key.StoreName, storeLocation, GetCurrentTime())), "RS256");
default:
throw new InvalidOperationException($"Invalid key type '{key.Type ?? "(null)"}'.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public async Task<IEndpointResult> ProcessAsync(HttpContext ctx)
var result = await _requestvalidator.ValidateAsync(parameters, user);
if (result.IsError)
{
_logger.LogError($"Error ending session {result.Error}");
_logger.LogError(LoggerEventIds.EndingSessionFailed, "Error ending session {Error}", result.Error);
return new RedirectResult(_identityServerOptions.Value.UserInteraction.ErrorUrl);
}

Expand Down
24 changes: 24 additions & 0 deletions src/Identity/ApiAuthorization.IdentityServer/src/LoggerEventIds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer
{
internal static class LoggerEventIds
{
public static readonly EventId ConfiguringAPIResource = new EventId(1, "ConfiguringAPIResource");
public static readonly EventId ConfiguringLocalAPIResource = new EventId(2, "ConfiguringLocalAPIResource");
public static readonly EventId ConfiguringClient = new EventId(3, "ConfiguringClient");
public static readonly EventId AllowedApplicationNotDefienedForIdentityResource = new EventId(4, "AllowedApplicationNotDefienedForIdentityResource");
public static readonly EventId AllApplicationsAllowedForIdentityResource = new EventId(5, "AllApplicationsAllowedForIdentityResource");
public static readonly EventId ApplicationsAllowedForIdentityResource = new EventId(6, "ApplicationsAllowedForIdentityResource");
public static readonly EventId AllowedApplicationNotDefienedForApiResource = new EventId(7, "AllowedApplicationNotDefienedForApiResource");
public static readonly EventId AllApplicationsAllowedForApiResource = new EventId(8, "AllApplicationsAllowedForApiResource");
public static readonly EventId ApplicationsAllowedForApiResource = new EventId(9, "ApplicationsAllowedForApiResource");
public static readonly EventId DevelopmentKeyLoaded = new EventId(10, "DevelopmentKeyLoaded");
public static readonly EventId CertificateLoadedFromFile = new EventId(11, "CertificateLoadedFromFile");
public static readonly EventId CertificateLoadedFromStore = new EventId(12, "CertificateLoadedFromStore");
public static readonly EventId EndingSessionFailed = new EventId(13, "EndingSessionFailed");
}
}
21 changes: 21 additions & 0 deletions src/Identity/Core/src/EventIds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.Identity
{
internal static class EventIds
{
public static EventId UserCannotSignInWithoutConfirmedEmail = new EventId(0, "UserCannotSignInWithoutConfirmedEmail");
public static EventId SecurityStampValidationFailed = new EventId(0, "SecurityStampValidationFailed");
public static EventId SecurityStampValidationFailedId4 = new EventId(4, "SecurityStampValidationFailed");
public static EventId UserCannotSignInWithoutConfirmedPhoneNumber = new EventId(1, "UserCannotSignInWithoutConfirmedPhoneNumber");
public static EventId InvalidPassword = new EventId(2, "InvalidPassword");
public static EventId UserLockedOut = new EventId(3, "UserLockedOut");
public static EventId UserCannotSignInWithoutConfirmedAccount = new EventId(4, "UserCannotSignInWithoutConfirmedAccount");
public static EventId TwoFactorSecurityStampValidationFailed = new EventId(5, "TwoFactorSecurityStampValidationFailed");
}
}
2 changes: 1 addition & 1 deletion src/Identity/Core/src/SecurityStampValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public virtual async Task ValidateAsync(CookieValidatePrincipalContext context)
}
else
{
Logger.LogDebug(0, "Security stamp validation failed, rejecting cookie.");
Logger.LogDebug(EventIds.SecurityStampValidationFailed, "Security stamp validation failed, rejecting cookie.");
context.RejectPrincipal();
await SignInManager.SignOutAsync();
}
Expand Down
14 changes: 7 additions & 7 deletions src/Identity/Core/src/SignInManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,17 @@ public virtual async Task<bool> CanSignInAsync(TUser user)
{
if (Options.SignIn.RequireConfirmedEmail && !(await UserManager.IsEmailConfirmedAsync(user)))
{
Logger.LogWarning(0, "User cannot sign in without a confirmed email.");
Logger.LogWarning(EventIds.UserCannotSignInWithoutConfirmedEmail, "User cannot sign in without a confirmed email.");
return false;
}
if (Options.SignIn.RequireConfirmedPhoneNumber && !(await UserManager.IsPhoneNumberConfirmedAsync(user)))
{
Logger.LogWarning(1, "User cannot sign in without a confirmed phone number.");
Logger.LogWarning(EventIds.UserCannotSignInWithoutConfirmedPhoneNumber, "User cannot sign in without a confirmed phone number.");
return false;
}
if (Options.SignIn.RequireConfirmedAccount && !(await _confirmation.IsConfirmedAsync(UserManager, user)))
{
Logger.LogWarning(4, "User cannot sign in without a confirmed account.");
Logger.LogWarning(EventIds.UserCannotSignInWithoutConfirmedAccount, "User cannot sign in without a confirmed account.");
return false;
}
return true;
Expand Down Expand Up @@ -278,7 +278,7 @@ public virtual async Task<TUser> ValidateSecurityStampAsync(ClaimsPrincipal prin
{
return user;
}
Logger.LogDebug(4, "Failed to validate a security stamp.");
Logger.LogDebug(EventIds.SecurityStampValidationFailedId4, "Failed to validate a security stamp.");
return null;
}

Expand All @@ -301,7 +301,7 @@ public virtual async Task<TUser> ValidateTwoFactorSecurityStampAsync(ClaimsPrinc
{
return user;
}
Logger.LogDebug(5, "Failed to validate a security stamp.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we have different event ids for the same message, 4 and 5 due to different methods

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kahbazi I think its fine to introduce the logging extensions to the API which wasn't currently using event ids, but it doesn't look like its worth the potential regression in modifying the event ids for the sign in manager/existing apis. Unless you want to introduce a line by line method, so maybe lets just revert/delete LogginExtensions, but keep the LoggerEventIds changes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to be consentience for each log. Should I delete LogginExtensions completely and add event id to each logs?
Or add another method to LogginExtensions for invalid security stamp?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right maybe the safest way to do it is https://github.com/dotnet/aspnetcore/pull/16879/files#diff-7d0bb5dd924f2d3e3de48da228cfbd19 so introduce a new file that's just the ids,, so no LoggingExtensions class like you said

Logger.LogDebug(EventIds.TwoFactorSecurityStampValidationFailed, "Failed to validate a security stamp.");
return null;
}

Expand Down Expand Up @@ -396,7 +396,7 @@ public virtual async Task<SignInResult> CheckPasswordSignInAsync(TUser user, str

return SignInResult.Success;
}
Logger.LogWarning(2, "User failed to provide the correct password.");
Logger.LogWarning(EventIds.InvalidPassword, "User failed to provide the correct password.");

if (UserManager.SupportsUserLockout && lockoutOnFailure)
{
Expand Down Expand Up @@ -837,7 +837,7 @@ protected virtual async Task<bool> IsLockedOut(TUser user)
/// <returns>A locked out SignInResult</returns>
protected virtual Task<SignInResult> LockedOut(TUser user)
{
Logger.LogWarning(3, "User is currently locked out.");
Logger.LogWarning(EventIds.UserLockedOut, "User is currently locked out.");
return Task.FromResult(SignInResult.LockedOut);
}

Expand Down
26 changes: 26 additions & 0 deletions src/Identity/Extensions.Core/src/LoggerEventIds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Identity.Core
{
internal static class LoggerEventIds
{
public static readonly EventId RoleValidationFailed = new EventId(0, "RoleValidationFailed");
public static readonly EventId InvalidPassword = new EventId(0, "InvalidPassword");
public static readonly EventId UserAlreadyHasPassword = new EventId(1, "UserAlreadyHasPassword");
public static readonly EventId ChangePasswordFailed = new EventId(2, "ChangePasswordFailed");
public static readonly EventId AddLoginFailed = new EventId(4, "AddLoginFailed");
public static readonly EventId UserAlreadyInRole = new EventId(5, "UserAlreadyInRole");
public static readonly EventId UserNotInRole = new EventId(6, "UserNotInRole");
public static readonly EventId PhoneNumberChanged = new EventId(7, "PhoneNumberChanged");
public static readonly EventId VerifyUserTokenFailed = new EventId(9, "VerifyUserTokenFailed");
public static readonly EventId VerifyTwoFactorTokenFailed = new EventId(10, "VerifyTwoFactorTokenFailed");
public static readonly EventId LockoutFailed = new EventId(11, "LockoutFailed");
public static readonly EventId UserLockedOut = new EventId(12, "UserLockedOut");
public static readonly EventId UserValidationFailed = new EventId(13, "UserValidationFailed");
public static readonly EventId PasswordValidationFailed = new EventId(14, "PasswordValidationFailed");
public static readonly EventId GetSecurityStampFailed = new EventId(15, "GetSecurityStampFailed");
}
}
2 changes: 1 addition & 1 deletion src/Identity/Extensions.Core/src/RoleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ protected virtual async Task<IdentityResult> ValidateRoleAsync(TRole role)
}
if (errors.Count > 0)
{
Logger.LogWarning(0, "Role {roleId} validation failed: {errors}.", await GetRoleIdAsync(role), string.Join(";", errors.Select(e => e.Code)));
Logger.LogWarning(LoggerEventIds.RoleValidationFailed, "Role {roleId} validation failed: {errors}.", await GetRoleIdAsync(role), string.Join(";", errors.Select(e => e.Code)));
return IdentityResult.Failed(errors.ToArray());
}
return IdentityResult.Success;
Expand Down
Loading