很抱歉问这么长的问题。我有一个使用身份asp.net核心的web应用程序。由于某些原因,我的web应用程序没有"注册",只有"登录"。这是因为用户注册将由另一个web应用程序完成。因此,我必须使用包含以下用户信息的自定义上下文:
public partial class CustomersInformationDBContext : IdentityDbContext<Customer>
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>(entity => {
entity.ToTable("Customers", "dbo");
entity.HasKey(e => new { e.Email })
.HasName("PK_Customers");
entity.Ignore(e => e.LockoutEnd);
entity.Ignore(e => e.Id);
entity.Ignore(e => e.AccessFailedCount);
entity.Ignore(e => e.LockoutEnabled);
entity.Ignore(e => e.PasswordHash);
entity.Ignore(e => e.EmailConfirmed);
entity.Ignore(e => e.PhoneNumber);
entity.Ignore(e => e.PhoneNumberConfirmed);
entity.Ignore(e => e.ConcurrencyStamp);
entity.Ignore(e => e.SecurityStamp);
entity.Ignore(e => e.TwoFactorEnabled);
});
}
Customer
是IdentityUser
:
public partial class Customer : IdentityUser
{
public int CustomerId { get; set; }
[Key]
public string Email { get; set; } = null!;
public string Username { get; set; } = null!;
public string? Password { get; set; }
public string TempPassword { get; set; } = null!;
public string? NormalizedUsername { get; set; } //Caps lock Username
public string? NormalizedEmail { get; set; } //Caps lock email
}
所以Customer
表为
CREATE TABLE [dbo].[Customers](
[CustomerId] [int] NOT NULL,
[Email] [nvarchar](320) NOT NULL,
[Username] [nvarchar](50) NOT NULL,
[Password] [nvarchar](max) NULL,
[TempPassword] [nvarchar](50) NOT NULL,
[NormalizedUsername] [nvarchar](256) NULL,
[NormalizedEmail] [nvarchar](256) NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[Email] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
在Login.cshtml.cs
中有OnPostAsync
方法,我在其中添加了以下行:
returnUrl ??= Url.Content("~/Customer/HomeProducts");
var user = await _userManager.FindByEmailAsync(Input.Email); //I've added this line
var result4 = await _userManager.CheckPasswordAsync(user, Input.Password); //this line returns FALSE
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(user.Username, user.Password, Input.RememberMe, lockoutOnFailure: false); //This line return FAILED. user.Username and user.Password are correct.
调试时,result
总是返回Failed,即使凭证是正确的!
也许这个自定义标识错过了一些强制性的东西,但我不能弄清楚缺少什么。
在我的Program.cs
中我添加了:
builder.Services.AddIdentityCore<Customer>(options =>
{
options.SignIn.RequireConfirmedAccount = false;
})
//.AddRoles<IdentityRole>()
.AddSignInManager<SignInManager<Customer>>()
.AddDefaultTokenProviders()
//.AddDefaultUI()
.AddEntityFrameworkStores<CustomersAdminSite.ModelScaffolding.CustomersInformationDBContext>();
builder.Services.AddRazorPages().AddRazorPagesOptions(options =>
{
options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "");
});
你能帮我一下吗?谢谢你!(对不起,我的英语不好)。
我想成功登录到我的web应用程序,因为凭证是正确的
. NET IdentityUserManager.CheckPasswordAsync()
通常对给定的密码进行哈希运算,并与存储在数据库中的PasswordHash
列进行比较。
您的代码显示您正在覆盖Customer
实体(基于IdentityUser
)以"忽略",即不将PasswordHash
字段持久化到数据库中。
我看到你已经添加了自己的Password
和TempPassword
列,但我看不到任何地方,你配置UserManager
使用这些字段(如果这甚至是一个选项)。
所以我假设CheckPasswordAsync()
返回false,因为它找不到PasswordHash字段。我有点惊讶在这种情况下它没有抛出异常。