diff --git a/Directory.Packages.props b/Directory.Packages.props
index cf6dbf6b28..e2ea3dc099 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -27,6 +27,7 @@
+
diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index b46a809403..3373a239de 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -465,6 +465,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.SkiaSharp.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.RemoteServices.Tests", "test\Volo.Abp.RemoteServices.Tests\Volo.Abp.RemoteServices.Tests.csproj", "{DACD4485-61BE-4DE5-ACAE-4FFABC122500}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Abstractions", "src\Volo.Abp.AspNetCore.Abstractions\Volo.Abp.AspNetCore.Abstractions.csproj", "{E1051CD0-9262-4869-832D-B951723F4DDE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1387,6 +1389,10 @@ Global
{DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1051CD0-9262-4869-832D-B951723F4DDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1051CD0-9262-4869-832D-B951723F4DDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1051CD0-9262-4869-832D-B951723F4DDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1051CD0-9262-4869-832D-B951723F4DDE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1621,6 +1627,7 @@ Global
{198683D0-7DC6-40F2-B81B-8E446E70A9DE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{DFAF8763-D1D6-4EB4-B459-20E31007FE2F} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{DACD4485-61BE-4DE5-ACAE-4FFABC122500} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {E1051CD0-9262-4869-832D-B951723F4DDE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml
new file mode 100644
index 0000000000..1715698ccd
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd
new file mode 100644
index 0000000000..ffa6fc4b78
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj
new file mode 100644
index 0000000000..c96dbc0c7b
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ netstandard2.0;netstandard2.1;net8.0
+ enable
+ Nullable
+ Volo.Abp.AspNetCore.Abstractions
+ Volo.Abp.AspNetCore.Abstractions
+ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81;
+ false
+ false
+ false
+
+
+
+
+
+
+
+
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs
new file mode 100644
index 0000000000..6a15c5550f
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AspNetCore.VirtualFileSystem;
+using Volo.Abp.AspNetCore.WebClientInfo;
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.AspNetCore;
+
+public class AbpAspNetCoreAbstractionsModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddSingleton();
+ context.Services.AddSingleton();;
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs
similarity index 100%
rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs
rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs
similarity index 100%
rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs
rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs
new file mode 100644
index 0000000000..a690c36062
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs
@@ -0,0 +1,22 @@
+using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.Primitives;
+
+namespace Volo.Abp.AspNetCore.VirtualFileSystem;
+
+public class NullWebContentFileProvider : IWebContentFileProvider
+{
+ public virtual IFileInfo GetFileInfo(string subpath)
+ {
+ return new NotFoundFileInfo(subpath);
+ }
+
+ public virtual IDirectoryContents GetDirectoryContents(string subpath)
+ {
+ return new NotFoundDirectoryContents();
+ }
+
+ public virtual IChangeToken Watch(string filter)
+ {
+ return NullChangeToken.Singleton;
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
similarity index 83%
rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
index abd92597d3..7cbb4ecae8 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
@@ -5,4 +5,6 @@ public interface IWebClientInfoProvider
string? BrowserInfo { get; }
string? ClientIpAddress { get; }
+
+ string? DeviceInfo { get; }
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs
new file mode 100644
index 0000000000..9b83ffa4f3
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs
@@ -0,0 +1,10 @@
+namespace Volo.Abp.AspNetCore.WebClientInfo;
+
+public class NullWebClientInfoProvider : IWebClientInfoProvider
+{
+ public virtual string? BrowserInfo { get; }
+
+ public virtual string? ClientIpAddress { get; }
+
+ public virtual string? DeviceInfo { get; }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
similarity index 83%
rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
index 740a79c884..cc1180fd20 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
@@ -3,7 +3,7 @@ using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.Client;
-internal static class MvcCachedApplicationConfigurationClientHelper
+public static class MvcCachedApplicationConfigurationClientHelper
{
public static string CreateCacheKey(ICurrentUser currentUser)
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs
index 738884fe06..f63c04e49c 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs
@@ -4,10 +4,12 @@ using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.Caching;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.Security.Claims;
+using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.Client;
@@ -18,17 +20,23 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
protected IDistributedCache Cache { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; }
+ protected IDistributedCache ApplicationConfigurationDtoCache { get; }
+ protected ICurrentUser CurrentUser { get; }
public RemoteDynamicClaimsPrincipalContributorCache(
IDistributedCache cache,
IHttpClientFactory httpClientFactory,
IOptions abpClaimsPrincipalFactoryOptions,
- IRemoteServiceHttpClientAuthenticator httpClientAuthenticator)
+ IRemoteServiceHttpClientAuthenticator httpClientAuthenticator,
+ IDistributedCache applicationConfigurationDtoCache,
+ ICurrentUser currentUser)
: base(abpClaimsPrincipalFactoryOptions)
{
Cache = cache;
HttpClientFactory = httpClientFactory;
HttpClientAuthenticator = httpClientAuthenticator;
+ ApplicationConfigurationDtoCache = applicationConfigurationDtoCache;
+ CurrentUser = currentUser;
}
protected async override Task GetCacheAsync(Guid userId, Guid? tenantId = null)
@@ -49,6 +57,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
catch (Exception e)
{
Logger.LogWarning(e, $"Failed to refresh remote claims for user: {userId}");
+ await ApplicationConfigurationDtoCache.RemoveAsync(MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser));
throw;
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
index 88b4506dc5..c6326e3e95 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
+++ b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
@@ -20,6 +20,7 @@
+
@@ -30,6 +31,7 @@
+
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
index bad4b7c491..cda6aea27f 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs
@@ -25,7 +25,8 @@ namespace Volo.Abp.AspNetCore;
typeof(AbpHttpModule),
typeof(AbpAuthorizationModule),
typeof(AbpValidationModule),
- typeof(AbpExceptionHandlingModule)
+ typeof(AbpExceptionHandlingModule),
+ typeof(AbpAspNetCoreAbstractionsModule)
)]
public class AbpAspNetCoreModule : AbpModule
{
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
index 9c62fa8b25..181aaf3ec8 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs
@@ -1,4 +1,6 @@
+using System;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -16,8 +18,26 @@ public class AbpDynamicClaimsMiddleware : AbpMiddlewareBase, ITransientDependenc
{
if (context.RequestServices.GetRequiredService>().Value.IsDynamicClaimsEnabled)
{
+ var authenticationType = context.User.Identity.AuthenticationType;
var abpClaimsPrincipalFactory = context.RequestServices.GetRequiredService();
context.User = await abpClaimsPrincipalFactory.CreateDynamicAsync(context.User);
+
+ if (context.User.Identity?.IsAuthenticated == false)
+ {
+ if (!authenticationType.IsNullOrWhiteSpace())
+ {
+ var authenticationSchemeProvider = context.RequestServices.GetRequiredService();
+ var scheme = await authenticationSchemeProvider.GetSchemeAsync(authenticationType);
+ if (scheme != null)
+ {
+ await context.SignOutAsync(scheme.Name);
+ }
+ }
+ else
+ {
+ await context.SignOutAsync();
+ }
+ }
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
index fffc35792a..9814dd8c97 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs
@@ -10,6 +10,7 @@ using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.VirtualFileSystem;
+[Dependency(ReplaceServices = true)]
public class WebContentFileProvider : IWebContentFileProvider, ISingletonDependency
{
private readonly IVirtualFileProvider _virtualFileProvider;
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs
index 3c44cda4e3..6e450efbcd 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs
@@ -1,10 +1,12 @@
using System;
+using DeviceDetectorNET;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.WebClientInfo;
+[Dependency(ReplaceServices = true)]
public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransientDependency
{
protected ILogger Logger { get; }
@@ -22,6 +24,8 @@ public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransie
public string? ClientIpAddress => GetClientIpAddress();
+ public string? DeviceInfo => GetDeviceInfo();
+
protected virtual string? GetBrowserInfo()
{
return HttpContextAccessor.HttpContext?.Request?.Headers?["User-Agent"];
@@ -39,4 +43,30 @@ public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransie
return null;
}
}
+
+ protected virtual string? GetDeviceInfo()
+ {
+ string? deviceInfo = null;
+ var deviceDetector = new DeviceDetector(GetBrowserInfo());
+ deviceDetector.Parse();
+ if (!deviceDetector.IsParsed())
+ {
+ return deviceInfo;
+ }
+
+ var osInfo = deviceDetector.GetOs();
+ if (osInfo.Success)
+ {
+ deviceInfo = osInfo.Match.Name;
+ }
+
+ var clientInfo = deviceDetector.GetClient();
+ if (clientInfo.Success)
+ {
+ deviceInfo = deviceInfo.IsNullOrWhiteSpace() ? clientInfo.Match.Name : deviceInfo + " " + clientInfo.Match.Name;
+ }
+
+ return deviceInfo;
+ }
+
}
diff --git a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
index 2661298405..0a89ba7a3f 100644
--- a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
+++ b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
@@ -276,4 +276,32 @@ public static class AbpClaimsIdentityExtensions
return principal;
}
+
+ public static string? FindSessionId([NotNull] this IIdentity identity)
+ {
+ Check.NotNull(identity, nameof(identity));
+
+ var claimsIdentity = identity as ClaimsIdentity;
+
+ var sessionIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.SessionId);
+ if (sessionIdOrNull == null || sessionIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ return sessionIdOrNull.Value;
+ }
+
+ public static string? FindSessionId([NotNull] this ClaimsPrincipal principal)
+ {
+ Check.NotNull(principal, nameof(principal));
+
+ var sessionIdOrNull = principal.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.SessionId);
+ if (sessionIdOrNull == null || sessionIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ return sessionIdOrNull.Value;
+ }
}
diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
index 3ce75e36d8..0e7f098174 100644
--- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
+++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
@@ -97,4 +97,9 @@ public static class AbpClaimTypes
/// Default: "remember_me".
///
public static string RememberMe { get; set; } = "remember_me";
+
+ ///
+ /// Default: "session_id".
+ ///
+ public static string SessionId { get; set; } = "session_id";
}
diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
index b702bcffde..e40c9a9fd7 100644
--- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
+++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
@@ -70,4 +70,16 @@ public static class CurrentUserExtensions
{
return currentUser.FindClaimValue(AbpClaimTypes.ImpersonatorUserName);
}
+
+ public static string GetSessionId([NotNull] this ICurrentUser currentUser)
+ {
+ var sessionId = currentUser.FindSessionId();
+ Debug.Assert(sessionId != null, "sessionId != null");
+ return sessionId!;
+ }
+
+ public static string? FindSessionId([NotNull] this ICurrentUser currentUser)
+ {
+ return currentUser.FindClaimValue(AbpClaimTypes.SessionId);
+ }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs
index 9b38e2e25a..d261068adb 100644
--- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs
+++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs
@@ -1,5 +1,7 @@
-using Microsoft.AspNetCore.Identity;
+using System;
+using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
using static Volo.Abp.Identity.AspNetCore.AbpSecurityStampValidatorCallback;
@@ -45,9 +47,11 @@ public class AbpIdentityAspNetCoreModule : AbpModule
public override void PostConfigureServices(ServiceConfigurationContext context)
{
- Configure(options =>
- {
- options.UpdatePrincipal();
- });
+ context.Services.AddOptions()
+ .Configure((securityStampValidatorOptions, serviceProvider) =>
+ {
+ var abpRefreshingPrincipalOptions = serviceProvider.GetRequiredService>().Value;
+ securityStampValidatorOptions.UpdatePrincipal(abpRefreshingPrincipalOptions);
+ });
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs
new file mode 100644
index 0000000000..55e9007d6c
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using Volo.Abp.Security.Claims;
+
+namespace Volo.Abp.Identity.AspNetCore;
+
+public class AbpRefreshingPrincipalOptions
+{
+ public List CurrentPrincipalKeepClaimTypes { get; set; }
+
+ public AbpRefreshingPrincipalOptions()
+ {
+ CurrentPrincipalKeepClaimTypes = new List
+ {
+ AbpClaimTypes.SessionId
+ };
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs
index 63bed70dfd..7108d30a5b 100644
--- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs
+++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs
@@ -1,5 +1,7 @@
using System.Linq;
+using System.Security.Principal;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.AspNetCore.Identity;
namespace Volo.Abp.Identity.AspNetCore;
@@ -17,8 +19,9 @@ public class AbpSecurityStampValidatorCallback
/// This is needed to preserve claims such as idp, auth_time, amr.
///
/// The context.
+ /// The AbpRefreshingPrincipalOptions.
///
- public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context)
+ public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context, AbpRefreshingPrincipalOptions refreshingPrincipalOptions)
{
var newClaimTypes = context.NewPrincipal.Claims.Select(x => x.Type).ToArray();
var currentClaimsToKeep = context.CurrentPrincipal.Claims.Where(x => !newClaimTypes.Contains(x.Type)).ToArray();
@@ -26,6 +29,18 @@ public class AbpSecurityStampValidatorCallback
var id = context.NewPrincipal.Identities.First();
id.AddClaims(currentClaimsToKeep);
+ if (refreshingPrincipalOptions.CurrentPrincipalKeepClaimTypes.Any())
+ {
+ foreach (var claimType in refreshingPrincipalOptions.CurrentPrincipalKeepClaimTypes)
+ {
+ var sessionIdClaim = context.CurrentPrincipal.Claims.FirstOrDefault(x => x.Type == claimType);
+ if (sessionIdClaim != null)
+ {
+ id.AddOrReplace(sessionIdClaim);
+ }
+ }
+ }
+
return Task.CompletedTask;
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs
index d1c51fbf41..009e170310 100644
--- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs
+++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs
@@ -5,12 +5,12 @@ namespace Volo.Abp.Identity.AspNetCore;
public static class SecurityStampValidatorOptionsExtensions
{
- public static SecurityStampValidatorOptions UpdatePrincipal(this SecurityStampValidatorOptions options)
+ public static SecurityStampValidatorOptions UpdatePrincipal(this SecurityStampValidatorOptions options, AbpRefreshingPrincipalOptions abpRefreshingPrincipalOptions)
{
var previousOnRefreshingPrincipal = options.OnRefreshingPrincipal;
options.OnRefreshingPrincipal = async context =>
{
- await SecurityStampValidatorCallback.UpdatePrincipal(context);
+ await SecurityStampValidatorCallback.UpdatePrincipal(context, abpRefreshingPrincipalOptions);
if(previousOnRefreshingPrincipal != null)
{
await previousOnRefreshingPrincipal.Invoke(context);
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs
new file mode 100644
index 0000000000..96cb8df5c9
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs
@@ -0,0 +1,14 @@
+namespace Volo.Abp.Identity;
+
+public class IdentitySessionConsts
+{
+ public static int MaxSessionIdLength { get; set; } = 128;
+
+ public static int MaxDeviceLength { get; set; } = 64;
+
+ public static int MaxDeviceInfoLength { get; set; } = 64;
+
+ public static int MaxClientIdLength { get; set; } = 64;
+
+ public static int MaxIpAddressesLength { get; set; } = 256;
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs
new file mode 100644
index 0000000000..ff8e470bae
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs
@@ -0,0 +1,10 @@
+namespace Volo.Abp.Identity;
+
+public static class IdentitySessionDevices
+{
+ public const string Web = "Web";
+
+ public const string OAuth = "OAuth";
+
+ public const string Mobile = "Mobile";
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs
index 2ceaa8ed4c..8a1e50795f 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs
@@ -10,7 +10,7 @@ public interface IIdentitySecurityLogRepository : IBasicRepository> GetListAsync(
string sorting = null,
- int maxResultCount = 50,
+ int maxResultCount = int.MaxValue,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs
new file mode 100644
index 0000000000..d40fbbcc95
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Repositories;
+
+namespace Volo.Abp.Identity;
+
+public interface IIdentitySessionRepository : IBasicRepository
+{
+ Task FindAsync(string sessionId, CancellationToken cancellationToken = default);
+
+ Task GetAsync(string sessionId, CancellationToken cancellationToken = default);
+
+ Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = int.MaxValue,
+ int skipCount = 0,
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default);
+
+ Task GetCountAsync(
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default);
+
+ Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default);
+
+ Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default);
+
+ Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default);
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs
new file mode 100644
index 0000000000..c25a6b2e82
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.MultiTenancy;
+
+namespace Volo.Abp.Identity;
+
+public class IdentitySession : BasicAggregateRoot, IMultiTenant
+{
+ public virtual string SessionId { get; protected set; }
+
+ ///
+ /// Web, Mobile ...
+ ///
+ public virtual string Device { get; protected set; }
+
+ public virtual string DeviceInfo { get; protected set; }
+
+ public virtual Guid? TenantId { get; protected set; }
+
+ public virtual Guid UserId { get; protected set; }
+
+ public virtual string ClientId { get; set; }
+
+ public virtual string IpAddresses { get; protected set; }
+
+ public virtual DateTime SignedIn { get; protected set; }
+
+ public virtual DateTime? LastAccessed { get; protected set; }
+
+ protected IdentitySession()
+ {
+
+ }
+
+ public IdentitySession(
+ Guid id,
+ string sessionId,
+ string device,
+ string deviceInfo,
+ Guid userId,
+ Guid? tenantId,
+ string clientId,
+ string ipAddresses,
+ DateTime signedIn,
+ DateTime? lastAccessed = null)
+ {
+ Id = id;
+ SessionId = sessionId;
+ Device = device;
+ DeviceInfo = deviceInfo;
+ UserId = userId;
+ TenantId = tenantId;
+ ClientId = clientId;
+ IpAddresses = ipAddresses;
+ SignedIn = signedIn;
+ LastAccessed = lastAccessed;
+ }
+
+ public void SetSignedInTime(DateTime signedIn)
+ {
+ SignedIn = signedIn;
+ }
+
+ public void UpdateLastAccessedTime(DateTime? lastAccessed)
+ {
+ LastAccessed = lastAccessed;
+ }
+
+ public void SetIpAddresses(IEnumerable ipAddresses)
+ {
+ IpAddresses = JoinAsString(ipAddresses);
+ }
+
+ public IEnumerable GetIpAddresses()
+ {
+ return GetArrayFromString(IpAddresses);
+ }
+
+ private static string JoinAsString(IEnumerable list)
+ {
+ var serialized = string.Join(",", list);
+ return serialized.IsNullOrWhiteSpace() ? null : serialized;
+ }
+
+ private string[] GetArrayFromString(string str)
+ {
+ return str?.Split(",", StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty();
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs
index a58a73a996..c9dcc70e68 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs
@@ -17,9 +17,10 @@ public class AbpIdentityEntityFrameworkCoreModule : AbpModule
options.AddRepository();
options.AddRepository();
options.AddRepository();
- options.AddRepository();
+ options.AddRepository();
options.AddRepository();
options.AddRepository();
+ options.AddRepository();
});
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs
similarity index 96%
rename from modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs
rename to modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs
index 0e5c2a9b4c..2043293395 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs
@@ -10,9 +10,9 @@ using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.Identity.EntityFrameworkCore;
-public class EFCoreIdentitySecurityLogRepository : EfCoreRepository, IIdentitySecurityLogRepository
+public class EfCoreIdentitySecurityLogRepository : EfCoreRepository, IIdentitySecurityLogRepository
{
- public EFCoreIdentitySecurityLogRepository(IDbContextProvider dbContextProvider)
+ public EfCoreIdentitySecurityLogRepository(IDbContextProvider dbContextProvider)
: base(dbContextProvider)
{
@@ -20,7 +20,7 @@ public class EFCoreIdentitySecurityLogRepository : EfCoreRepository> GetListAsync(
string sorting = null,
- int maxResultCount = 50,
+ int maxResultCount = int.MaxValue,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs
new file mode 100644
index 0000000000..222ecf5886
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Dynamic.Core;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.Timing;
+
+namespace Volo.Abp.Identity.EntityFrameworkCore;
+
+public class EfCoreIdentitySessionRepository : EfCoreRepository, IIdentitySessionRepository
+{
+ public EfCoreIdentitySessionRepository(IDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+
+ }
+
+ public virtual async Task FindAsync(string sessionId, CancellationToken cancellationToken = default)
+ {
+ return await (await GetDbSetAsync()).FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task GetAsync(string sessionId, CancellationToken cancellationToken = default)
+ {
+ var session = await FindAsync(sessionId, cancellationToken);
+ if (session == null)
+ {
+ throw new EntityNotFoundException(typeof(IdentitySession));
+ }
+
+ return session;
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = int.MaxValue,
+ int skipCount = 0,
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await (await GetDbSetAsync())
+ .WhereIf(userId.HasValue, x => x.UserId == userId)
+ .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device)
+ .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId)
+ .OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting)
+ .PageBy(skipCount, maxResultCount)
+ .ToListAsync(GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task GetCountAsync(
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await (await GetDbSetAsync())
+ .WhereIf(userId.HasValue, x => x.UserId == userId)
+ .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device)
+ .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId)
+ .LongCountAsync(GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default)
+ {
+ await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken);
+ }
+
+ public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default)
+ {
+ await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken);
+ }
+
+ public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default)
+ {
+ var now = LazyServiceProvider.LazyGetRequiredService().Now;
+ await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken);
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs
index 2f409a61b2..6fe3b8dd9b 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs
@@ -20,4 +20,6 @@ public interface IIdentityDbContext : IEfCoreDbContext
DbSet LinkUsers { get; }
DbSet UserDelegations { get; }
+
+ DbSet Sessions { get; }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs
index 79adece5e1..3bb7777cb4 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs
@@ -24,6 +24,8 @@ public class IdentityDbContext : AbpDbContext, IIdentityDbCon
public DbSet UserDelegations { get; set; }
+ public DbSet Sessions { get; set; }
+
public IdentityDbContext(DbContextOptions options)
: base(options)
{
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
index f85f72e84e..f94f4690cc 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
@@ -279,6 +279,25 @@ public static class IdentityDbContextModelBuilderExtensions
b.ApplyObjectExtensionMappings();
});
+ builder.Entity(b =>
+ {
+ b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Sessions", AbpIdentityDbProperties.DbSchema);
+
+ b.ConfigureByConvention();
+
+ b.Property(x => x.SessionId).HasMaxLength(IdentitySessionConsts.MaxSessionIdLength).IsRequired();
+ b.Property(x => x.Device).HasMaxLength(IdentitySessionConsts.MaxDeviceLength).IsRequired();
+ b.Property(x => x.DeviceInfo).HasMaxLength(IdentitySessionConsts.MaxDeviceInfoLength);
+ b.Property(x => x.ClientId).HasMaxLength(IdentitySessionConsts.MaxClientIdLength);
+ b.Property(x => x.IpAddresses).HasMaxLength(IdentitySessionConsts.MaxIpAddressesLength);
+
+ b.HasIndex(x => x.SessionId);
+ b.HasIndex(x => x.Device );
+ b.HasIndex(x => new { x.TenantId, x.UserId });
+
+ b.ApplyObjectExtensionMappings();
+ });
+
builder.TryConfigureObjectExtensions();
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs
index 90118a534e..86995f5472 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs
@@ -21,6 +21,8 @@ public class AbpIdentityMongoDbContext : AbpMongoDbContext, IAbpIdentityMongoDbC
public IMongoCollection UserDelegations => Collection();
+ public IMongoCollection Sessions => Collection();
+
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs
index 5ee7ffc47e..4ccb9fe7f7 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs
@@ -42,5 +42,10 @@ public static class AbpIdentityMongoDbContextExtensions
{
b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "UserDelegations";
});
+
+ builder.Entity(b =>
+ {
+ b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "Sessions";
+ });
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs
index 35c81b25bb..8537bf630f 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs
@@ -21,6 +21,7 @@ public class AbpIdentityMongoDbModule : AbpModule
options.AddRepository();
options.AddRepository();
options.AddRepository();
+ options.AddRepository();
});
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs
index 39bcc23b50..7481afe5ac 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs
@@ -20,4 +20,6 @@ public interface IAbpIdentityMongoDbContext : IAbpMongoDbContext
IMongoCollection LinkUsers { get; }
IMongoCollection UserDelegations { get; }
+
+ IMongoCollection Sessions { get; }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs
index de5587d8d9..6a875444f9 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs
@@ -21,7 +21,7 @@ public class MongoIdentitySecurityLogRepository :
public virtual async Task> GetListAsync(
string sorting = null,
- int maxResultCount = 50,
+ int maxResultCount = int.MaxValue,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs
new file mode 100644
index 0000000000..957699d4d7
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Dynamic.Core;
+using System.Threading;
+using System.Threading.Tasks;
+using MongoDB.Driver;
+using MongoDB.Driver.Linq;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories.MongoDB;
+using Volo.Abp.MongoDB;
+using Volo.Abp.Timing;
+
+namespace Volo.Abp.Identity.MongoDB;
+
+public class MongoIdentitySessionRepository : MongoDbRepository, IIdentitySessionRepository
+{
+ public MongoIdentitySessionRepository(IMongoDbContextProvider dbContextProvider)
+ : base(dbContextProvider)
+ {
+
+ }
+
+ public virtual async Task FindAsync(string sessionId, CancellationToken cancellationToken = default)
+ {
+ return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken)))
+ .As>()
+ .FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task GetAsync(string sessionId, CancellationToken cancellationToken = default)
+ {
+ var session = await FindAsync(sessionId, cancellationToken);
+ if (session == null)
+ {
+ throw new EntityNotFoundException(typeof(IdentitySession));
+ }
+
+ return session;
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = int.MaxValue,
+ int skipCount = 0,
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken)))
+ .WhereIf(userId.HasValue, x => x.UserId == userId)
+ .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device)
+ .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId)
+ .OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting)
+ .PageBy(skipCount, maxResultCount)
+ .As>()
+ .ToListAsync(GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task GetCountAsync(
+ Guid? userId = null,
+ string device = null,
+ string clientId = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken)))
+ .WhereIf(userId.HasValue, x => x.UserId == userId)
+ .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device)
+ .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId)
+ .As>()
+ .LongCountAsync(GetCancellationToken(cancellationToken));
+ }
+
+ public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default)
+ {
+ await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken);
+ }
+
+ public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default)
+ {
+ await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken);
+ }
+
+ public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default)
+ {
+ var now = LazyServiceProvider.LazyGetRequiredService().Now;
+ await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken);
+ }
+}
diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs
index 7a5b3d2835..370b23a856 100644
--- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs
+++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs
@@ -26,6 +26,12 @@ public class AbpDefaultOpenIddictClaimsPrincipalHandler : IAbpOpenIddictClaimsPr
continue;
}
+ if (claim.Type == AbpClaimTypes.SessionId)
+ {
+ claim.SetDestinations(OpenIddictConstants.Destinations.AccessToken, OpenIddictConstants.Destinations.IdentityToken);
+ continue;
+ }
+
switch (claim.Type)
{
case OpenIddictConstants.Claims.PreferredUsername:
diff --git a/nupkg/common.ps1 b/nupkg/common.ps1
index 78de2aef44..9f014cd526 100644
--- a/nupkg/common.ps1
+++ b/nupkg/common.ps1
@@ -97,6 +97,7 @@ $projects = (
"framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer",
"framework/src/Volo.Abp.AspNetCore.Authentication.OAuth",
"framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect",
+ "framework/src/Volo.Abp.AspNetCore.Abstractions",
"framework/src/Volo.Abp.AspNetCore",
"framework/src/Volo.Abp.AspNetCore.Mvc.Dapr",
"framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus",
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs
similarity index 97%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs
index 2f3a437364..b97eb71e95 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs
@@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
{
[DbContext(typeof(MyProjectNameDbContext))]
- [Migration("20240125061235_Initial")]
+ [Migration("20240312033651_Initial")]
partial class Initial
{
///
@@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs
similarity index 96%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs
index dd96c605e7..39c3b550b9 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs
@@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
+ migrationBuilder.CreateTable(
+ name: "AbpSessions",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false),
+ DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ TenantId = table.Column(type: "uniqueidentifier", nullable: true),
+ UserId = table.Column(type: "uniqueidentifier", nullable: false),
+ ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ SignedIn = table.Column(type: "datetime2", nullable: false),
+ LastAccessed = table.Column(type: "datetime2", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AbpSessions", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "AbpSettingDefinitions",
columns: table => new
@@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_Device",
+ table: "AbpSessions",
+ column: "Device");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_SessionId",
+ table: "AbpSessions",
+ column: "SessionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_TenantId_UserId",
+ table: "AbpSessions",
+ columns: new[] { "TenantId", "UserId" });
+
migrationBuilder.CreateIndex(
name: "IX_AbpSettingDefinitions_Name",
table: "AbpSettingDefinitions",
@@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
+ migrationBuilder.DropTable(
+ name: "AbpSessions");
+
migrationBuilder.DropTable(
name: "AbpSettingDefinitions");
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
index 652e7b674d..0a52057acc 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
@@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs
similarity index 97%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs
index f25d60e99b..84ee9411af 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs
@@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(MyProjectNameDbContext))]
- [Migration("20240125061501_Initial")]
+ [Migration("20240312033906_Initial")]
partial class Initial
{
///
@@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs
similarity index 97%
rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs
index 9fc3a5a0b9..a3dbf4a768 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs
@@ -45,27 +45,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpAuditLogs", x => x.Id);
});
- migrationBuilder.CreateTable(
- name: "AbpBackgroundJobs",
- columns: table => new
- {
- Id = table.Column(type: "uniqueidentifier", nullable: false),
- JobName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
- JobArgs = table.Column(type: "nvarchar(max)", maxLength: 1048576, nullable: false),
- TryCount = table.Column(type: "smallint", nullable: false, defaultValue: (short)0),
- CreationTime = table.Column(type: "datetime2", nullable: false),
- NextTryTime = table.Column(type: "datetime2", nullable: false),
- LastTryTime = table.Column(type: "datetime2", nullable: true),
- IsAbandoned = table.Column(type: "bit", nullable: false, defaultValue: false),
- Priority = table.Column(type: "tinyint", nullable: false, defaultValue: (byte)15),
- ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false),
- ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AbpBackgroundJobs", x => x.Id);
- });
-
migrationBuilder.CreateTable(
name: "AbpClaimTypes",
columns: table => new
@@ -276,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
+ migrationBuilder.CreateTable(
+ name: "AbpSessions",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false),
+ DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ TenantId = table.Column(type: "uniqueidentifier", nullable: true),
+ UserId = table.Column(type: "uniqueidentifier", nullable: false),
+ ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ SignedIn = table.Column(type: "datetime2", nullable: false),
+ LastAccessed = table.Column(type: "datetime2", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AbpSessions", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "AbpSettingDefinitions",
columns: table => new
@@ -802,11 +801,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpAuditLogs",
columns: new[] { "TenantId", "UserId", "ExecutionTime" });
- migrationBuilder.CreateIndex(
- name: "IX_AbpBackgroundJobs_IsAbandoned_NextTryTime",
- table: "AbpBackgroundJobs",
- columns: new[] { "IsAbandoned", "NextTryTime" });
-
migrationBuilder.CreateIndex(
name: "IX_AbpEntityChanges_AuditLogId",
table: "AbpEntityChanges",
@@ -922,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_Device",
+ table: "AbpSessions",
+ column: "Device");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_SessionId",
+ table: "AbpSessions",
+ column: "SessionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_TenantId_UserId",
+ table: "AbpSessions",
+ columns: new[] { "TenantId", "UserId" });
+
migrationBuilder.CreateIndex(
name: "IX_AbpSettingDefinitions_Name",
table: "AbpSettingDefinitions",
@@ -1022,9 +1031,6 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpAuditLogActions");
- migrationBuilder.DropTable(
- name: "AbpBackgroundJobs");
-
migrationBuilder.DropTable(
name: "AbpClaimTypes");
@@ -1061,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
+ migrationBuilder.DropTable(
+ name: "AbpSessions");
+
migrationBuilder.DropTable(
name: "AbpSettingDefinitions");
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
index 72f44ed239..d74eefbde1 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs
@@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs
similarity index 97%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs
index 364eaa6b57..309ac9f973 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs
@@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Host.Migrations
{
[DbContext(typeof(MyProjectNameDbContext))]
- [Migration("20240125061101_Initial")]
+ [Migration("20240321011533_Initial")]
partial class Initial
{
///
@@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Host.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs
similarity index 96%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs
index bfb34fcaad..e36cf69df7 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs
@@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Host.Migrations
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
+ migrationBuilder.CreateTable(
+ name: "AbpSessions",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false),
+ DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ TenantId = table.Column(type: "uniqueidentifier", nullable: true),
+ UserId = table.Column(type: "uniqueidentifier", nullable: false),
+ ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ SignedIn = table.Column(type: "datetime2", nullable: false),
+ LastAccessed = table.Column(type: "datetime2", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AbpSessions", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "AbpSettingDefinitions",
columns: table => new
@@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Host.Migrations
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_Device",
+ table: "AbpSessions",
+ column: "Device");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_SessionId",
+ table: "AbpSessions",
+ column: "SessionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_TenantId_UserId",
+ table: "AbpSessions",
+ columns: new[] { "TenantId", "UserId" });
+
migrationBuilder.CreateIndex(
name: "IX_AbpSettingDefinitions_Name",
table: "AbpSettingDefinitions",
@@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Host.Migrations
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
+ migrationBuilder.DropTable(
+ name: "AbpSessions");
+
migrationBuilder.DropTable(
name: "AbpSettingDefinitions");
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs
index f2b46a651f..f2ef0d1071 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs
@@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Host.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs
similarity index 97%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs
index 54929eb8e9..fc604df03b 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs
@@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Mvc.Migrations
{
[DbContext(typeof(MyProjectNameDbContext))]
- [Migration("20240125061143_Initial")]
+ [Migration("20240312033558_Initial")]
partial class Initial
{
///
@@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs
similarity index 96%
rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs
rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs
index 44eddb6abb..88e57c1ebb 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs
@@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
+ migrationBuilder.CreateTable(
+ name: "AbpSessions",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false),
+ DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ TenantId = table.Column(type: "uniqueidentifier", nullable: true),
+ UserId = table.Column(type: "uniqueidentifier", nullable: false),
+ ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true),
+ IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ SignedIn = table.Column(type: "datetime2", nullable: false),
+ LastAccessed = table.Column(type: "datetime2", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AbpSessions", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "AbpSettingDefinitions",
columns: table => new
@@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_Device",
+ table: "AbpSessions",
+ column: "Device");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_SessionId",
+ table: "AbpSessions",
+ column: "SessionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AbpSessions_TenantId_UserId",
+ table: "AbpSessions",
+ columns: new[] { "TenantId", "UserId" });
+
migrationBuilder.CreateIndex(
name: "IX_AbpSettingDefinitions_Name",
table: "AbpSettingDefinitions",
@@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
+ migrationBuilder.DropTable(
+ name: "AbpSessions");
+
migrationBuilder.DropTable(
name: "AbpSettingDefinitions");
diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs
index 8041069541..17a23b24a7 100644
--- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs
+++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs
@@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Device");
+
+ b.HasIndex("SessionId");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSessions", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property("Id")
diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
index e1afd1a339..3e317d5cd8 100644
--- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs
@@ -46,7 +46,7 @@ public class MyProjectNameDbContext :
public DbSet SecurityLogs { get; set; }
public DbSet LinkUsers { get; set; }
public DbSet UserDelegations { get; set; }
-
+ public DbSet Sessions { get; set; }
// Tenant Management
public DbSet Tenants { get; set; }
public DbSet TenantConnectionStrings { get; set; }
diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs
similarity index 94%
rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs
rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs
index b6dd932e2f..bd99dc092f 100644
--- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs
+++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs
@@ -12,8 +12,8 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
- [DbContext(typeof(AuthServerDbContext))]
- [Migration("20240125061344_Initial")]
+ [DbContext(typeof(MyProjectNameDbContext))]
+ [Migration("20240322114004_Initial")]
partial class Initial
{
///
@@ -290,6 +290,66 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpEntityPropertyChanges", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .IsRequired()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("ExtraProperties")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsAbandoned")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false);
+
+ b.Property("JobArgs")
+ .IsRequired()
+ .HasMaxLength(1048576)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("NextTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Priority")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint")
+ .HasDefaultValue((byte)15);
+
+ b.Property("TryCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0);
+
+ b.HasKey("Id");
+
+ b.HasIndex("IsAbandoned", "NextTryTime");
+
+ b.ToTable("AbpBackgroundJobs", (string)null);
+ });
+
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b =>
{
b.Property("Id")
@@ -415,7 +475,6 @@ namespace MyCompanyName.MyProjectName.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property("Id")
- .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property("ConcurrencyStamp")
@@ -464,7 +523,6 @@ namespace MyCompanyName.MyProjectName.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
{
b.Property("Id")
- .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property("SourceTenantId")
@@ -491,7 +549,6 @@ namespace MyCompanyName.MyProjectName.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property("Id")
- .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property("ConcurrencyStamp")
@@ -573,7 +630,6 @@ namespace MyCompanyName.MyProjectName.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property("Id")
- .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property("Action")
@@ -647,10 +703,60 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpSecurityLogs", (string)null);
});
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Device")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("DeviceInfo")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("IpAddresses")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("LastAccessed")
+ .HasColumnType("datetime2");
+
+ b.Property("SessionId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("SignedIn")
+ .HasColumnType("datetime2");
+
+ b.Property