[英]Correct use of Microsoft.AspNet.Identity 2.0
我迷失了使用MVC 5模板附帶的身份驗證方法。
我需要將CreateBy用戶包含在一個名為client的實體中,所以經過一些研究我得出了這個:
模型:
[Table("Clients")]
public partial class Client
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual int UserCreated_Id { get; set; }
[ForeignKey("UserCreated_Id")]
public virtual ApplicationUser UserCreated { get; set; }
}
控制器方法:
client.UserCreated_Id = User.Identity.GetUserId<int>();
但我必須改變身份模型中的幾乎所有內容:
從
public class ApplicationUser : IdentityUser
至
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
因此,差不多有30個變化。
但現在我有2個DbContext:
身份背景:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
public ApplicationDbContext() : base("IPDB") {}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
我的應用背景:
public class MyDbContext : DbContext
{
public MyDbContext() : base("IPDB")
{
// Tells Entity Framework that we will handle the creation of the database manually for all the projects in the solution
Database.SetInitializer<MyDbContext>(null);
}
public DbSet<Client> Clients { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// ANOTHER CHANGE I HAD TO MADE TO BE ABLE TO SCAFFOLDING
modelBuilder.Entity<ApplicationUserLogin>().HasKey<int>(l => l.UserId);
modelBuilder.Entity<ApplicationRole>().HasKey<int>(r => r.Id);
modelBuilder.Entity<ApplicationUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
}
我現在的問題是:
拜托,我需要一些明確的指導,因為我現在非常困惑,我真的很想建立優秀的代碼,我認為情況並非如此。
我需要2個DbContext嗎?
對於一些人來說,擁有身份的DbContext和其他應用程序的其他內容被認為是一種很好的做法。 但它不是強制性的,我認為沒有必要。
你不應該有大的dbcontexts,較小的上下文更快。 這意味着有時您必須創建多個dbcontext。 我相信每個上下文50個實體就足夠了。
我是否正確地將用戶與客戶端實體相關聯?
你不是(在我看來)。 ApplicationUser
使用Guid
(默認情況下)來表示其主鍵值,而不是Int32
。 所以,而不是這個:
public virtual int UserCreated_Id { get; set; }
[ForeignKey("UserCreated_Id")]
public virtual ApplicationUser UserCreated { get; set; }
你應該使用它(記得刪除UserCreated_Id
中的虛擬):
public Guid UserCreated_Id { get; set; }
[ForeignKey("UserCreated_Id")]
public virtual ApplicationUser UserCreated { get; set; }
在你的上下文中,這應該足夠了:
public class ApplicationUser : IdentityUser
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
我需要創建一個包含所有用戶和附加信息的列表,我是否會從2個DbContext中讀取信息?
是的,你可能會,但我不認為這是一個很大的性能交易,因為它不會導致任何額外的數據庫查詢,考慮到你當時只使用1個dbcontext。
拜托,我需要一些明確的指導,因為我現在非常困惑,我真的很想建立優秀的代碼,我認為情況並非如此。
你喜歡干凈的代碼嗎? 所以,這里有我的提示(基於我的觀點) :忘記ASP.NET IDENTITY! 身份是一個糟糕的解決方案,它不會分離,混淆和不必要。
您可以使用自定義用戶實體創建自己的登錄系統。 使用此https://crackstation.net/hashing-security.htm#aspsourcecode來散列密碼和此MVC身份驗證 - 最簡單的方法來創建OWIN身份驗證
ASP.NET Identity 2.0非常靈活,同時還提供了一些在mose情況下可以執行的下降默認實現。 MVC 5模板在大多數地方使用默認實現,但在某些情況下,添加了一些額外的東西以使定制更容易。
ASP.NET內部始終使用IdentityUser<...>
。 所有這些模板參數都提供了一種選擇自己的密鑰類型的方法,這意味着您還必須選擇自己的IdentityUserRole類型(因為它包含密鑰)。
還有使用字符串作為鍵的便捷默認實現。 字符串的值是GUID的字符串表示形式。
public class IdentityUser :
IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
{
/// <summary>
/// Constructor which creates a new Guid for the Id
/// </summary>
public IdentityUser()
{
this.Id = Guid.NewGuid().ToString();
}
在數據庫中將字符串作為主鍵並不常見,但對於安全性敏感的東西,它是有意義的。 數據庫之間復制的數據不存在沖突ID的風險,從而給用戶提供錯誤的權限。
在您的情況下,您需要選擇:使用字符串PK的默認實現或將id更改為int。 在后一種情況下,您必須如您所發現的那樣更改身份模型中的“幾乎所有內容”。 雖然我認為你可以不用實現自己的ApplicationRole
。 應該可以將ApplicationUser
聲明為
public class ApplicationUser: IdentityUser<int, IdentityUserLogin<int>, IdentityUserRole<int>....>
在大多數情況下,單個DbContext
適用於應用程序。 如果使用多個DbContexts,則它們應該用於彼此不相關的不同的不同數據集。 當您將Client
類設置為與ApplicationUser
相關時,它們應該都在同一個DbContext
。 模板試圖通過命名ApplicationDbContext
來傳達應用程序上下文的主DbContext
應繼承IdentityDbContext<>
的想法。 使用那個,並用你自己的東西擴展它。 我通常重命名它並將其移動到其他地方,但我仍然只有一個DbContext
並讓它繼承IdentityDbContext<>
。
除非你真的,真的知道你在做什么 - 不要推出自己的身份解決方案。 使用已通過外部審核加強安全性的現有項目。 如果您對ASP.NET Identity不滿意,可以查看Brock Allen的Identity重啟 。
為了可信度(是的,我今天是賞金獵人): 官方的ASP.NET文檔鏈接到我的博客 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.