C# 如何使用Identity&;在.NET Core 2.0中管理身份验证和身份验证;实体框架
导言 在过去的几天里,我一直在从事一个小型pet项目,目标是学习.NET Core 2.0,其身份由Entity Framework Core支持。它是一个典型的“WebAPI”类型的项目,具有基于cookie的身份验证和基于声明的授权。它被一些客户端应用程序(SPA)使用 代码 在Startup.cs中以这种方式配置授权和身份验证流C# 如何使用Identity&;在.NET Core 2.0中管理身份验证和身份验证;实体框架,c#,asp.net-identity,asp.net-core-2.0,asp.net-core-webapi,C#,Asp.net Identity,Asp.net Core 2.0,Asp.net Core Webapi,导言 在过去的几天里,我一直在从事一个小型pet项目,目标是学习.NET Core 2.0,其身份由Entity Framework Core支持。它是一个典型的“WebAPI”类型的项目,具有基于cookie的身份验证和基于声明的授权。它被一些客户端应用程序(SPA)使用 代码 在Startup.cs中以这种方式配置授权和身份验证流 services .AddIdentity<ApplicationUser, IdentityRole> () .AddEntityF
services
.AddIdentity<ApplicationUser, IdentityRole> ()
.AddEntityFrameworkStores<ApplicationDbContext> ()
.AddDefaultTokenProviders ();
services
.AddAuthentication (sharedOptions => {
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie ();
服务
.额外性()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
服务
.AddAuthentication(sharedOptions=>{
sharedOptions.DefaultAuthenticateScheme=CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignenscheme=CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie();
我的登录控制器操作如下所示:
[HttpPost]
[Route ("login")]
public async Task<IActionResult> Login ([FromBody] LogInCredentialsModel credentials) {
// Get User for given UserName
var user = await userManager.Users.FirstOrDefaultAsync (p => p.UserName == credentials.UserName);
//User not found
if (user == default (ApplicationUser))
return StatusCode (400);
// Check if password is correct
var result = await signInManager.PasswordSignInAsync (user, credentials.Password, true, false);
if (result.Succeeded) {
//Basic claims with Name and Email
List<Claim> claims = new List<Claim> {
new Claim (ClaimTypes.Name, user.UserName),
new Claim (ClaimTypes.Email, user.Email)
};
var userRoles = await this.GetUserRoles (user); // Custom helper method to get list of user roles
// Add Role claims
foreach (var role in userRoles) {
claims.Add (new Claim (ClaimTypes.Role, role));
}
ClaimsIdentity identity = new ClaimsIdentity (claims, CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal = new ClaimsPrincipal (identity);
// Sign in using cookie scheme
await HttpContext.SignInAsync (CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties {
IsPersistent = true,
});
return Ok ();
} else {
return StatusCode (400);
}
}
[HttpPost]
[路线(“登录”)]
公共异步任务登录([FromBody]LoginRedentialsModel凭据){
//获取给定用户名的用户
var user=await userManager.Users.FirstOrDefaultAsync(p=>p.UserName==credentials.UserName);
//找不到用户
如果(用户==默认值(应用程序用户))
返回状态码(400);
//检查密码是否正确
var result=await-signInManager.PasswordSignInAsync(用户、凭据、密码、true、false);
if(result.successed){
//带有姓名和电子邮件的基本索赔
清单索赔=新清单{
新索赔(ClaimTypes.Name、user.UserName),
新索赔(ClaimTypes.Email、user.Email)
};
var userRoles=wait this.GetUserRoles(user);//获取用户角色列表的自定义帮助器方法
//添加角色声明
foreach(userRoles中的var角色){
添加(新索赔(ClaimTypes.Role,Role));
}
ClaimsIdentity identity=新的ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);
ClaimsPrincipal principal=新的ClaimsPrincipal(标识);
//使用cookie方案登录
等待HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,主体,新AuthenticationProperties{
ispersist=true,
});
返回Ok();
}否则{
返回状态码(400);
}
}
问题
你的两个问题的答案都很基本,所以也许你应该花更多的时间和文档在一起,以便更好地处理这个问题。也就是说:
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
自动散列密码,尝试使用该用户名(电子邮件地址)和散列密码检索用户,然后创建一个包含所有信息的ClaimsPrincipal
,如果成功。一劳永逸那么你在问什么问题。。。1.还是2。?请每个问题一个问题。这是同一机制的两个方面,这就是为什么它们包含在一个问题中。快速浏览meta.stackoverflow.com让我相信这是允许的。@你为什么要用这种方式手工构建
ClaimsPrincipal
?这应该由框架为您处理。@trailmax感谢您的输入。我这样做是为了让我的跟踪和错误代码正常工作。为什么框架没有在我的实例中处理它?请参阅下面Chris Pratt回答下的我的评论。问题是,当我使用SignInManager登录时,我看到设置了一些cookie,但this.User.Identity.IsAuthenticated返回false,[Authorize]属性阻止客户端访问路由。好的,我想我发现了代码的问题所在。在注册服务的启动代码中,我调用AddAuthentication(…)和AddCookie(…),它们用于配置无标识的cookie身份验证。当我移除这部分时,一切都开始正常工作。谢谢克里斯,你把我推向了正确的方向。