Browse Source

Refactoring ISecurityLogManager.

pull/4675/head
maliming 6 years ago
parent
commit
73de02689f
  1. 2
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs
  2. 17
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/DefaultSecurityLogManager.cs
  3. 7
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogManager.cs
  4. 2
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SecurityLogInfo.cs
  5. 9
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs
  6. 40
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
  7. 14
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs
  8. 28
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  9. 7
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs
  10. 37
      modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SignInResultExtensions.cs
  11. 33
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogActionConsts.cs
  12. 11
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogIdentityConsts.cs
  13. 12
      modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs
  14. 18
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/SecurityLogEvent.cs
  15. 85
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/SecurityLogHandler.cs

2
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs

@ -49,7 +49,7 @@ namespace Volo.Abp.AspNetCore.SecurityLog
WebClientInfoProvider = webClientInfoProvider;
}
public override async Task<SecurityLogInfo> CreateAsync()
protected override async Task<SecurityLogInfo> CreateAsync()
{
var securityLogInfo = await base.CreateAsync();

17
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/DefaultSecurityLogManager.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -18,17 +19,19 @@ namespace Volo.Abp.SecurityLog
SecurityLogOptions = securityLogOptions.Value;
}
public virtual Task<SecurityLogInfo> CreateAsync()
public async Task SaveAsync(Action<SecurityLogInfo> saveAction)
{
var securityLogInfo = await CreateAsync();
saveAction?.Invoke(securityLogInfo);
await SecurityLogStore.SaveAsync(securityLogInfo);
}
protected virtual Task<SecurityLogInfo> CreateAsync()
{
return Task.FromResult(new SecurityLogInfo
{
ApplicationName = SecurityLogOptions.ApplicationName
});
}
public async Task SaveAsync(SecurityLogInfo securityLogInfo)
{
await SecurityLogStore.SaveAsync(securityLogInfo);
}
}
}

7
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogManager.cs

@ -1,11 +1,10 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace Volo.Abp.SecurityLog
{
public interface ISecurityLogManager
{
Task<SecurityLogInfo> CreateAsync();
Task SaveAsync(SecurityLogInfo securityLogInfo);
Task SaveAsync(Action<SecurityLogInfo> saveAction);
}
}

2
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SecurityLogInfo.cs

@ -35,8 +35,6 @@ namespace Volo.Abp.SecurityLog
public string ClientId { get; set; }
public string ClientName { get; set; }
public string CorrelationId { get; set; }
public string ClientIpAddress { get; set; }

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

@ -14,6 +14,8 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Volo.Abp.Account.Settings;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SecurityLog;
using Volo.Abp.Settings;
@ -128,7 +130,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await CreateSecurityLog("Login_" + result);
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
if (result.RequiresTwoFactor)
{

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

@ -6,7 +6,9 @@ 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;
@ -26,20 +28,22 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
protected SignInManager<IdentityUser> SignInManager { get; }
protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; }
protected ISecurityLogManager SecurityLogManager { get; }
protected ILocalEventBus LocalEventBus { get; }
public AccountController(
SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager,
ISettingProvider settingProvider,
ISecurityLogManager securityLogManager)
ISecurityLogManager securityLogManager,
ILocalEventBus localEventBus)
{
LocalizationResource = typeof(AccountResource);
SignInManager = signInManager;
UserManager = userManager;
SettingProvider = settingProvider;
SecurityLogManager = securityLogManager;
LocalEventBus = localEventBus;
}
[HttpPost]
@ -51,23 +55,33 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
ValidateLoginInfo(login);
await ReplaceEmailToUsernameOfInputIfNeeds(login);
var loginResult = GetAbpLoginResult(await SignInManager.PasswordSignInAsync(
var signInResult = await SignInManager.PasswordSignInAsync(
login.UserNameOrEmailAddress,
login.Password,
login.RememberMe,
true
));
);
await CreateSecurityLog("Login_" + loginResult.Result);
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = signInResult.ToIdentitySecurityLogAction(),
UserName = login.UserNameOrEmailAddress
});
return loginResult;
return GetAbpLoginResult(signInResult);
}
[HttpGet]
[Route("logout")]
public virtual async Task Logout()
{
await CreateSecurityLog("Logout");
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
}
@ -133,7 +147,7 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
}
return new AbpLoginResult(LoginResultType.Success);
return new AbpLoginResult(LoginResultType.Succeeded);
}
protected virtual void ValidateLoginInfo(UserLoginInfo login)
@ -161,13 +175,5 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
throw new UserFriendlyException(L["LocalLoginDisabledMessage"]);
}
}
protected virtual async Task CreateSecurityLog(string action)
{
var securityLog = await SecurityLogManager.CreateAsync();
securityLog.Identity = "Web";
securityLog.Action = action;
await SecurityLogManager.SaveAsync(securityLog);
}
}
}

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

@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
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 Volo.Abp.SecurityLog;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.Account.Web.Pages.Account
@ -17,7 +15,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
{
public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; }
public ISecurityLogManager SecurityLogManager { get; }
public ILocalEventBus LocalEventBus { get; set; }
protected AccountPageModel()
{
@ -79,13 +77,5 @@ namespace Volo.Abp.Account.Web.Pages.Account
{
return "~/"; //TODO: ???
}
protected virtual async Task CreateSecurityLog(string action)
{
var securityLog = await SecurityLogManager.CreateAsync();
securityLog.Identity = "Web";
securityLog.Action = action;
await SecurityLogManager.SaveAsync(securityLog);
}
}
}

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

@ -13,11 +13,12 @@ using System.Threading.Tasks;
using Volo.Abp.Account.Settings;
using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.Security.Claims;
using Volo.Abp.SecurityLog;
using Volo.Abp.Settings;
using Volo.Abp.Validation;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
namespace Volo.Abp.Account.Web.Pages.Account
{
@ -95,7 +96,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await CreateSecurityLog(result.ToString());
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
if (result.RequiresTwoFactor)
{
@ -184,7 +190,14 @@ namespace Volo.Abp.Account.Web.Pages.Account
bypassTwoFactor: true
);
await CreateSecurityLog(result.ToString());
if (!result.Succeeded)
{
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = "Login" + result
});
}
if (result.IsLockedOut)
{
@ -208,6 +221,15 @@ namespace Volo.Abp.Account.Web.Pages.Account
var user = await CreateExternalUserAsync(info);
await SignInManager.SignInAsync(user, false);
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = user.Name,
TenantId = user.TenantId
});
return RedirectSafely(returnUrl, returnUrlHash);
}

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

@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Web.Pages.Account
{
@ -15,6 +16,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
public virtual async Task<IActionResult> OnGetAsync()
{
await LocalEventBus.PublishAsync(new SecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
if (ReturnUrl != null)
{

37
modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SignInResultExtensions.cs

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

33
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogActionConsts.cs

@ -0,0 +1,33 @@
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogActionConsts
{
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";
public static string Logout { get; set; } = "Logout";
public static string ChangeUserName { get; set; } = "ChangeUserName";
public static string ChangeEmail { get; set; } = "ChangeEmail";
public static string ChangePhoneNumber { get; set; } = "ChangePhoneNumber";
public static string ChangePassword { get; set; } = "ChangePassword";
public static string TwoFactorEnabled { get; set; } = "TwoFactorEnabled";
public static string TwoFactorDisabled { get; set; } = "TwoFactorDisabled";
}
}

11
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogIdentityConsts.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.Identity
{
public static class IdentitySecurityLogIdentityConsts
{
public static string Identity { get; set; } = "Identity";
public static string IdentityExternal { get; set; } = "IdentityExternal";
public static string IdentityTwoFactor { get; set; } = "IdentityTwoFactor";
}
}

12
modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Globalization;
using Microsoft.Extensions.Localization;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
using Volo.Abp.Text.Formatting;
namespace Microsoft.AspNetCore.Identity
@ -48,12 +49,15 @@ namespace Microsoft.AspNetCore.Identity
if (!localizedString.ResourceNotFound)
{
var englishLocalizedString = localizer.WithCulture(CultureInfo.GetCultureInfo("en"))[key];
if (!englishLocalizedString.ResourceNotFound)
using (CultureHelper.Use(CultureInfo.GetCultureInfo("en")))
{
if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, out var values))
var englishLocalizedString = localizer[key];
if (!englishLocalizedString.ResourceNotFound)
{
return string.Format(localizedString.Value, values.Cast<object>().ToArray());
if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, out var values))
{
return string.Format(localizedString.Value, values.Cast<object>().ToArray());
}
}
}
}

18
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/SecurityLogEvent.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity
{
public class SecurityLogEvent : IMultiTenant
{
public Guid? TenantId { get; set; }
public string Identity { get; set; }
public string Action { get; set; }
public string UserName { get; set; }
public string ClientId { get; set; }
}
}

85
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/SecurityLogHandler.cs

@ -0,0 +1,85 @@
using System;
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 SecurityLogHandler : ILocalEventHandler<SecurityLogEvent>, ITransientDependency
{
protected ISecurityLogManager SecurityLogManager { get; }
protected IdentityUserManager UserManager { get; }
protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; }
protected IUserClaimsPrincipalFactory<IdentityUser> UserClaimsPrincipalFactory { get; }
protected ICurrentUser CurrentUser { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public SecurityLogHandler(
ISecurityLogManager securityLogManager,
IdentityUserManager userManager,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IUserClaimsPrincipalFactory<IdentityUser> userClaimsPrincipalFactory,
ICurrentUser currentUser,
IUnitOfWorkManager unitOfWorkManager)
{
SecurityLogManager = securityLogManager;
UserManager = userManager;
CurrentPrincipalAccessor = currentPrincipalAccessor;
UserClaimsPrincipalFactory = userClaimsPrincipalFactory;
CurrentUser = currentUser;
UnitOfWorkManager = unitOfWorkManager;
}
public async Task HandleEventAsync(SecurityLogEvent eventData)
{
Action<SecurityLogInfo> securityLogAction = securityLog =>
{
securityLog.Identity = eventData.Identity;
securityLog.Action = eventData.Action;
if (securityLog.UserName.IsNullOrWhiteSpace())
{
securityLog.UserName = eventData.UserName;
}
if (securityLog.ClientId.IsNullOrWhiteSpace())
{
securityLog.ClientId = eventData.ClientId;
}
};
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
if (CurrentUser.IsAuthenticated)
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
else
{
if (eventData.UserName.IsNullOrWhiteSpace())
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
else
{
var user = await UserManager.FindByNameAsync(eventData.UserName);
if (user != null)
{
using (CurrentPrincipalAccessor.Change(await UserClaimsPrincipalFactory.CreateAsync(user)))
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
}
}
}
await uow.CompleteAsync();
}
}
}
}
Loading…
Cancel
Save