diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsOptions.cs
new file mode 100644
index 0000000000..11345e5b0e
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsOptions.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using Volo.Abp.Security.Claims;
+
+namespace Volo.Abp.AspNetCore.Security.Claims;
+
+public class AbpDynamicClaimsOptions
+{
+ ///
+ /// List of the claims that will be dynamically added/overriden to the current principal.
+ /// Default values are:
+ /// -
+ /// -
+ /// -
+ /// -
+ /// -
+ /// -
+ ///
+ public List DynamicClaims { get; } = new();
+
+ public string RemoteRefreshUrl { get; set; } = "/api/account/refresh-dynamic-claims";
+
+ public AbpDynamicClaimsOptions()
+ {
+ DynamicClaims.Add(AbpClaimTypes.UserName);
+ DynamicClaims.Add(AbpClaimTypes.Role);
+ DynamicClaims.Add(AbpClaimTypes.Email);
+ DynamicClaims.Add(AbpClaimTypes.EmailVerified);
+ DynamicClaims.Add(AbpClaimTypes.PhoneNumber);
+ DynamicClaims.Add(AbpClaimTypes.PhoneNumberVerified);
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/DynamicClaimService.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/DynamicClaimService.cs
new file mode 100644
index 0000000000..2c7df05c8e
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/DynamicClaimService.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Caching.Distributed;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.AspNetCore.Security.Claims;
+
+/* This will be used by DynamicClaimsMiddleware to get dynamic claims
+ * and override the claims in the current principle.
+ */
+public class DynamicClaimService : IDynamicClaimService, ITransientDependency
+{
+ public Task GetClaimsAsync()
+ {
+ /* TODO:
+ * - If current user is not authenticated, return empty array.
+ * - Try to get from distributed cache for the current user, if available
+ * - If not available, call IDynamicClaimRefreshService.RefreshAsync()
+ * Then check from distributed cache again. If still not found, ignore it.
+ */
+
+ throw new NotImplementedException();
+ }
+}
+
+public interface IDynamicClaimRefreshService
+{
+ Task RefreshAsync();
+}
+
+[Dependency(TryRegister = true)]
+public class NullDynamicClaimRefreshService : IDynamicClaimRefreshService, ISingletonDependency
+{
+ public Task RefreshAsync()
+ {
+ /* TODO: Set distributed cache with an empty claim list
+ */
+ throw new NotImplementedException();
+
+ /* TODO:
+ * IDynamicClaimRefreshService will have more implementations:
+ * - AccountDynamicClaimRefreshService is the real implementation
+ * that constructs claims using UserManager.
+ * It will be effective in a monolith application, where the account
+ * module is installed in the application
+ * - RemoteDynamicClaimRefreshService is used in a system (like a microservice solution)
+ * where the account module is located remotely. In that case, we make a REST call
+ * to the account service.
+ * RemoteDynamicClaimRefreshService should be registered only if
+ * NullDynamicClaimRefreshService is used. I mean AccountDynamicClaimRefreshService
+ * (in-process implementation) should work by default if available.
+ * RemoteDynamicClaimRefreshService uses AbpDynamicClaimsOptions.RemoteRefreshUrl (and issuer)
+ */
+ }
+}
+
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/IDynamicClaimService.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/IDynamicClaimService.cs
new file mode 100644
index 0000000000..9160961bb2
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/IDynamicClaimService.cs
@@ -0,0 +1,9 @@
+using System.Security.Claims;
+using System.Threading.Tasks;
+
+namespace Volo.Abp.AspNetCore.Security.Claims;
+
+public interface IDynamicClaimService
+{
+ Task GetClaimsAsync();
+}
\ No newline at end of file