Browse Source

Use IdentitySecurityLogManager instead EventBus to save security logs.

https://github.com/abpframework/abp/pull/4675#issuecomment-660089083
pull/4810/head
maliming 6 years ago
parent
commit
83aeea2230
  1. 2
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs
  2. 2
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs
  3. 16
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
  4. 3
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs
  5. 6
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  6. 2
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs
  7. 7
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogContext.cs
  8. 26
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogManager.cs
  9. 19
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityServerSecurityLogActionConsts.cs
  10. 7
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityServerSecurityLogIdentityConsts.cs
  11. 25
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs
  12. 37
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/SignInResultExtensions.cs

2
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs

@ -132,7 +132,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),

2
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
public override async Task<IActionResult> OnGetAsync()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout

16
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs

@ -6,10 +6,8 @@ using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Settings;
using Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.SecurityLog;
using Volo.Abp.Settings;
using Volo.Abp.Validation;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
@ -28,22 +26,20 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
protected SignInManager<IdentityUser> SignInManager { get; }
protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; }
protected ILocalEventBus LocalEventBus { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
public AccountController(
SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager,
ISettingProvider settingProvider,
ISecurityLogManager securityLogManager,
ILocalEventBus localEventBus)
IdentitySecurityLogManager identitySecurityLogManager)
{
LocalizationResource = typeof(AccountResource);
SignInManager = signInManager;
UserManager = userManager;
SettingProvider = settingProvider;
LocalEventBus = localEventBus;
IdentitySecurityLogManager = identitySecurityLogManager;
}
[HttpPost]
@ -62,7 +58,7 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
true
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = signInResult.ToIdentitySecurityLogAction(),
@ -76,13 +72,13 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
[Route("logout")]
public virtual async Task Logout()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
await SignInManager.SignOutAsync();
}
[HttpPost]

3
modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs

@ -5,7 +5,6 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Identity;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
@ -15,7 +14,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
{
public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; }
public ILocalEventBus LocalEventBus { get; set; }
public IdentitySecurityLogManager IdentitySecurityLogManager { get; set; }
protected AccountPageModel()
{

6
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs

@ -98,7 +98,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
@ -194,7 +194,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
if (!result.Succeeded)
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = "Login" + result
@ -224,7 +224,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
await SignInManager.SignInAsync(user, false);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),

2
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs

@ -16,7 +16,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
public virtual async Task<IActionResult> OnGetAsync()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout

7
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogEvent.cs → modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogContext.cs

@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogEvent : IMultiTenant
public class IdentitySecurityLogContext
{
public Guid? TenantId { get; set; }
@ -18,12 +17,12 @@ namespace Volo.Abp.Identity
public Dictionary<string, object> ExtraProperties { get; }
public IdentitySecurityLogEvent()
public IdentitySecurityLogContext()
{
ExtraProperties = new Dictionary<string, object>();
}
public virtual IdentitySecurityLogEvent WithProperty(string key, object value)
public virtual IdentitySecurityLogContext WithProperty(string key, object value)
{
ExtraProperties[key] = value;
return this;

26
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogHandler.cs → modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogManager.cs

@ -2,15 +2,13 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.Security.Claims;
using Volo.Abp.SecurityLog;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogHandler : ILocalEventHandler<IdentitySecurityLogEvent>, ITransientDependency
public class IdentitySecurityLogManager : ITransientDependency
{
protected ISecurityLogManager SecurityLogManager { get; }
protected IdentityUserManager UserManager { get; }
@ -18,7 +16,7 @@ namespace Volo.Abp.Identity
protected IUserClaimsPrincipalFactory<IdentityUser> UserClaimsPrincipalFactory { get; }
protected ICurrentUser CurrentUser { get; }
public IdentitySecurityLogHandler(
public IdentitySecurityLogManager(
ISecurityLogManager securityLogManager,
IdentityUserManager userManager,
ICurrentPrincipalAccessor currentPrincipalAccessor,
@ -32,24 +30,24 @@ namespace Volo.Abp.Identity
CurrentUser = currentUser;
}
public async Task HandleEventAsync(IdentitySecurityLogEvent eventData)
public async Task SaveAsync(IdentitySecurityLogContext context)
{
Action<SecurityLogInfo> securityLogAction = securityLog =>
{
securityLog.Identity = eventData.Identity;
securityLog.Action = eventData.Action;
securityLog.Identity = context.Identity;
securityLog.Action = context.Action;
if (securityLog.UserName.IsNullOrWhiteSpace())
if (!context.UserName.IsNullOrWhiteSpace())
{
securityLog.UserName = eventData.UserName;
securityLog.UserName = context.UserName;
}
if (securityLog.ClientId.IsNullOrWhiteSpace())
if (!context.ClientId.IsNullOrWhiteSpace())
{
securityLog.ClientId = eventData.ClientId;
securityLog.ClientId = context.ClientId;
}
foreach (var property in eventData.ExtraProperties)
foreach (var property in context.ExtraProperties)
{
securityLog.ExtraProperties[property.Key] = property.Value;
}
@ -61,13 +59,13 @@ namespace Volo.Abp.Identity
}
else
{
if (eventData.UserName.IsNullOrWhiteSpace())
if (context.UserName.IsNullOrWhiteSpace())
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
else
{
var user = await UserManager.FindByNameAsync(eventData.UserName);
var user = await UserManager.FindByNameAsync(context.UserName);
if (user != null)
{
using (CurrentPrincipalAccessor.Change(await UserClaimsPrincipalFactory.CreateAsync(user)))

19
modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityServerSecurityLogActionConsts.cs

@ -0,0 +1,19 @@
namespace Volo.Abp.IdentityServer
{
public class IdentityServerSecurityLogActionConsts
{
public static string LoginSucceeded { get; set; } = "LoginSucceeded";
public static string LoginLockedout { get; set; } = "LoginLockedout";
public static string LoginNotAllowed { get; set; } = "LoginNotAllowed";
public static string LoginRequiresTwoFactor { get; set; } = "LoginRequiresTwoFactor";
public static string LoginFailed { get; set; } = "LoginFailed";
public static string LoginInvalidUserName { get; set; } = "LoginInvalidUserName";
public static string LoginInvalidUserNameOrPassword { get; set; } = "LoginInvalidUserNameOrPassword";
}
}

7
modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/IdentityServerSecurityLogIdentityConsts.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.IdentityServer
{
public class IdentityServerSecurityLogIdentityConsts
{
public static string IdentityServer { get; set; } = "IdentityServer";
}
}

25
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs

@ -10,6 +10,7 @@ using IdentityServer4.Validation;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.Localization;
using Volo.Abp.Security.Claims;
using Volo.Abp.Uow;
@ -23,18 +24,21 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
protected SignInManager<IdentityUser> SignInManager { get; }
protected IEventService Events { get; }
protected UserManager<IdentityUser> UserManager { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected ILogger<ResourceOwnerPasswordValidator<IdentityUser>> Logger { get; }
protected IStringLocalizer<AbpIdentityServerResource> Localizer { get; }
public AbpResourceOwnerPasswordValidator(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IdentitySecurityLogManager identitySecurityLogManager,
IEventService events,
ILogger<ResourceOwnerPasswordValidator<IdentityUser>> logger,
ILogger<ResourceOwnerPasswordValidator<IdentityUser>> logger,
IStringLocalizer<AbpIdentityServerResource> localizer)
{
UserManager = userManager;
SignInManager = signInManager;
IdentitySecurityLogManager = identitySecurityLogManager;
Events = events;
Logger = logger;
Localizer = localizer;
@ -71,6 +75,12 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
additionalClaims.ToArray()
);
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer,
Action = result.ToIdentitySecurityLogAction(),
});
return;
}
else if (result.IsLockedOut)
@ -91,12 +101,25 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive: false));
errorDescription = Localizer["InvalidUserNameOrPassword"];
}
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer,
Action = result.ToIdentitySecurityLogAction(),
UserName = context.UserName
});
}
else
{
Logger.LogInformation("No user found matching username: {username}", context.UserName);
await Events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive: false));
errorDescription = Localizer["InvalidUsername"];
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer,
Action = IdentityServerSecurityLogActionConsts.LoginInvalidUserName
});
}
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, errorDescription);

37
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/SignInResultExtensions.cs

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Identity;
namespace Volo.Abp.IdentityServer.AspNetIdentity
{
public static class SignInResultExtensions
{
public static string ToIdentitySecurityLogAction(this SignInResult result)
{
if (result.Succeeded)
{
return IdentityServerSecurityLogActionConsts.LoginSucceeded;
}
if (result.IsLockedOut)
{
return IdentityServerSecurityLogActionConsts.LoginLockedout;
}
if (result.RequiresTwoFactor)
{
return IdentityServerSecurityLogActionConsts.LoginRequiresTwoFactor;
}
if (result.IsNotAllowed)
{
return IdentityServerSecurityLogActionConsts.LoginNotAllowed;
}
if (!result.Succeeded)
{
return IdentityServerSecurityLogActionConsts.LoginFailed;
}
return IdentityServerSecurityLogActionConsts.LoginFailed;
}
}
}
Loading…
Cancel
Save