我正在尋找一種方法來禁用的,而不是從系統中刪除用戶,這是爲了保持相關數據的數據完整性。但似乎ASPNET身份只提供刪除帳戶。禁用用戶2.0
有一個新的鎖定功能,但它似乎閉鎖可以控制禁用的用戶,但是隻有特定數量的不正確的密碼嘗試後出鎖定用戶。
還有其他的選擇嗎?
我正在尋找一種方法來禁用的,而不是從系統中刪除用戶,這是爲了保持相關數據的數據完整性。但似乎ASPNET身份只提供刪除帳戶。禁用用戶2.0
有一個新的鎖定功能,但它似乎閉鎖可以控制禁用的用戶,但是隻有特定數量的不正確的密碼嘗試後出鎖定用戶。
還有其他的選擇嗎?
當您創建安裝了標識位的網站,您的網站將有一個名爲「IdentityModels.cs」文件。在這個文件中是一個名爲ApplicationUser的類,它繼承自IdentityUser。
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
書中有評論一個很好的鏈接,便於點擊here
本教程告訴你到底你需要做的,爲您的用戶添加自定義屬性是什麼。
而實際上,甚至不打擾看教程。
1)屬性添加到ApplicationUser類,如:
public bool? IsEnabled { get; set; }
2)在你的數據庫的AspNetUsers表上同一名稱添加一列。
3)繁榮,就是這樣!
現在在你的AccountController,你有一個註冊的動作如下:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email, IsEnabled = true };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
我已經添加了的IsEnabled =上創建ApplicationUser對象的真實。該值現在將保留在AspNetUsers表的新列中。
然後,您需要通過重寫ApplicationSignInManager中的PasswordSignInAsync來處理檢查此值作爲登錄過程的一部分。
我做到了,如下所示:
public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool rememberMe, bool shouldLockout)
{
var user = UserManager.FindByEmailAsync(userName).Result;
if ((user.IsEnabled.HasValue && !user.IsEnabled.Value) || !user.IsEnabled.HasValue)
{
return Task.FromResult<SignInStatus>(SignInStatus.LockedOut);
}
return base.PasswordSignInAsync(userName, password, rememberMe, shouldLockout);
}
您的情況可能有所不同,您可能不希望返回SignInStatus,但你的想法。
您需要引入自己的標誌到自定義IdentityUser派生類和實現/執行自己的邏輯關於啓用/禁用和防止用戶如果禁用登錄。
那麼賬戶鎖定怎麼樣。我大致看看,看起來我不應該用它來達到這個目的,對吧? – anIBMer
在v2中,由於暴力破解密碼,對帳號鎖定提供了一些支持。 –
您不需要創建自定義屬性。訣竅是在身份用戶上設置 LockoutEnabled
屬性並將代碼中的LockoutoutEndDateUtc
設置爲未來日期以鎖定用戶。然後,調用UserManager.IsLockedOutAsync(user.Id
)將返回false。
LockoutEnabled
和LockoutoutEndDateUtc
都必須符合鎖定用戶的真實和未來日期標準。例如,如果LockoutoutEndDateUt
的c值是2014-01-01 00:00:00.000
而LockoutEnabled
是true
,則調用UserManager.IsLockedOutAsync(user.Id)
仍將返回true
。我可以看到微軟爲什麼這樣設計它,所以你可以設置一個用戶被鎖定多長時間的時間跨度。
但是,我認爲應該是LockoutEnabled
爲true
,那麼如果LockoutoutEndDateUtc
爲空或未來的日期,那麼用戶應該被鎖定。這樣,你不必在你的代碼擔心設置兩個屬性(LockoutoutEndDateUtc
是NULL
默認情況下)。你可以只設置LockoutEnabled
到true
如果LockoutoutEndDateUtc
是NULL
用戶被無限期鎖定。
它已被提升了很多,但這個答案是錯誤的,因爲正如其他人所說的,你誤解了LockoutEnabled屬性。它表明用戶是否「可以被鎖定」。那裏應該是一個內置的屬性,簡稱爲「LockedOut」或類似的。更多信息:http://www.jamessturtevant.com/posts/ASPNET-Identity-Lockout/ – ozz
LockoutEnabled爲true,並且將來的LockoutEndDateUtc意味着.IsLockedOutAsync爲TRUE,而不是false。 (1st ppg。)如果2014-01-01是過去的(就像它最初發布時那樣),.IsLockedOutAsync將「仍然」返回FALSE,不正確。第三點是一個模糊的概念。這是怎麼得到任何upvotes? – fortboise
是的,你是對的,2014-01-01是錯誤的 - 它應該是未來的日期,比如DateTime.MaxValue。如果LockoutEnabled配置爲true,那麼當用戶檢查配置的MaxFailedAccessAttempts的數量時,LockoutEndate字段將從當前時間設置爲DefaultLockoutTimeSpan配置的任何值。正如你所提到的,我的第三個ppg有點含糊。簡而言之,我同意應該有一個bool字段來標記一個人是否被鎖定,並且不必手動編寫代碼將未來的日期設置到LockoutEnd字段來完成同樣的事情。 –
User
的默認LockoutEnabled
屬性不是指示用戶當前是否被鎖定的屬性。這表示使用者是否應該受到封鎖或沒有,一旦AccessFailedCount
達到MaxFailedAccessAttemptsBeforeLockout
值的屬性。即使用戶被鎖定,它也只是一種臨時措施,禁止用戶在LockedoutEnddateUtc
期間的財產。因此,要永久禁用或暫停的用戶帳戶,您可能希望引入自己的標誌財產。
完全同意,謝謝 – anIBMer
您可以使用這些類... ASP.NET標識的乾淨實現... 這是我自己的代碼。如果您希望主鍵的不同類型可以更改,則此處爲主鍵。
IdentityConfig.cs
public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationContext>()));
manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
manager.UserLockoutEnabledByDefault = false;
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser, int>(
dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
public class ApplicationSignInManager : SignInManager<ApplicationUser, int>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
base(userManager, authenticationManager) { }
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
public class ApplicationRoleManager : RoleManager<ApplicationRole, int>
{
public ApplicationRoleManager(IRoleStore<ApplicationRole, int> store)
: base(store)
{
}
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, int, ApplicationUserRole>
{
public ApplicationRoleStore(ApplicationContext db)
: base(db)
{
}
}
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, int,
ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
public ApplicationUserStore(ApplicationContext db)
: base(db)
{
}
}
IdentityModel.cs
public class ApplicationUser : IdentityUser<int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
//your property
//flag for users state (active, deactive or enabled, disabled)
//set it false to disable users
public bool IsActive { get; set; }
public ApplicationUser()
{
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class ApplicationUserRole : IdentityUserRole<int>
{
}
public class ApplicationLogin : IdentityUserLogin<int>
{
public virtual ApplicationUser User { get; set; }
}
public class ApplicationClaim : IdentityUserClaim<int>
{
public virtual ApplicationUser User { get; set; }
}
public class ApplicationRole : IdentityRole<int, ApplicationUserRole>
{
public ApplicationRole()
{
}
}
public class ApplicationContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationLogin, ApplicationUserRole, ApplicationClaim>
{
//web config connectionStringName DefaultConnection change it if required
public ApplicationContext()
: base("DefaultConnection")
{
Database.SetInitializer<ApplicationContext>(new CreateDatabaseIfNotExists<ApplicationContext>());
}
public static ApplicationContext Create()
{
return new ApplicationContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
}
這一切其實我做的事:
var lockoutEndDate = new DateTime(2999,01,01);
UserManager.SetLockoutEnabled(userId,true);
UserManager.SetLockoutEndDate(userId, lockoutEndDate);
這基本上是啓用鎖定(如果你不這樣做默認情況下,然後將鎖定結束日期設置爲一些遙遠的價值。
這對我來說非常合適,謝謝! – Rob10e
您是否需要檢查用戶是否存在以阻止user.IsEnabled上的NRE?我有以下內容:'if(user!= null &&!user.IsEnabled) { return Task.FromResult(SignInStatus.LockedOut); }'。我不檢查HasValue的原因是因爲我使IsEnabled成爲必填字段 –