长话短说:上文我们讲了 ASP.NET Core 基于声明的访问控制到底是什么鬼?

今天我们乘胜追击:聊一聊ASP.NET Core 中的身份验证。

身份验证是确定用户身份的过程。 授权是确定用户是否有权访问资源的过程。

1. 万变不离其宗

显而易见,一个常规的身份认证用例包括两部分:

① 对用户进行身份验证

② 在未经身份验证的用户试图访问受限资源时作出反应

已注册的身份验证处理程序及其配置选项被称为“方案”,方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。

我们口头上常说的:

基于cookie认证方案,若认证成功,go on,若认证失败则跳转回登录页面;

基于基本身份认证(BA)方案,若认证成功,go on,若认证失败则给浏览器返回WWW-Authenticate标头, 浏览器会再次弹出认证窗口。

2. ASP.NET Core认证原理

在 ASP.NET Core 中,身份验证由IAuthenticationService负责,身份验证服务会调用已注册的身份验证处理程序来完成与身份验证相关的操作, 整个验证过程由认证中间件来串联。

一图以蔽之:

其中有几个关键步骤

  1. 认证处理程序

    可结合方案Scheme中的配置项AuthenticationSchemeOptions编写认证处理程序。

    基于Cookie的认证方案可在Options项中可指定登录地址,

    基于基本身份的认证方案可在Options项中指定用户名/密码;

  2. 身份认证程序继承自AuthenticationHandler类IAuthenticationHandler接口

  • 核心认证函数可落地基于声明的访问控制,生成绑定了ClaimsPrincipal、Scheme的AuthenticationTicket对象; 无论认证成功/失败,函数返回AuthenticateResult对象

  • 挑战(对未认证的用户做出的反应): 例如返回登录页面

  • 禁止(对已认证,但对特定资源无权访问做出的反应) : 例如返回提示字符串

以上均为服务注册过程

  1. 收到请求,认证中间件使用IAuthenticationService对HttpContext按照要求的scheme进行认证, 实际内部会调用第2步编写的认证处理程序。

以上认证原理,之前有一个近身实战: ASP.NET Core 实现基本身份验证。

源代码如下: https://www.cnblogs.com/JulianHuang/p/10345365.html

3. ASP.NET Core获取当前用户

基于声明的访问控制, 我们会在HttpContext.User属性存储身份信息。

 var claims = new[] {
new Claim(ClaimTypes.NameIdentifier,username),
new Claim(ClaimTypes.Name,username),
};
var identity = new ClaimsIdentity(claims, Scheme.Name);
var principal = new ClaimsPrincipal(identity);
Context.User = principal;

Web应用程序中获取当前登录用户, 有两种代码场合:

3.1 在控制器中获取当前登录用户

控制器是处理请求的 一等公民,天生自带HttpContext。

直接通过ControllerBase基类中包含的HttpContext属性,获取User对象。

实际上Razor Page、Razor View、Middleware均包含HttpContext属性/参数, 可直接使用。

3.2 在服务中获取当前登录用户

这个时候,服务是作为请求处理中的一个环节,并没有直接可用的HttpContext。

ASP.NET Core 提供了IHttpContextAccessor类能够注入此次请求中的HttpContext对象(依赖注入框架的作用)。

//  下面的用户实体类,需要获取当前登录用户,借助IHttpContextAccessor注入httpContext
public class UserEntityService : IUserEntityService
{
private IHttpContextAccessor _accessor;
private readonly IMongoCollection<UserProfile> _users; public UserEntityService(IHttpContextAccessor accessor, IDefaultMongoDatabaseProvider databaseProvider)
{
_accessor = accessor;
_users = databaseProvider.GetCollection<UserProfile>(CollectionNames.UserProfiles);
} public Task<UserProfile> GetCurrentUserAsync()
{
var rawUser = this._accessor.HttpContext.User();
if (rawUser == null)
{
return null;
}
var filter = Builders<UserProfile>.Filter.Eq("UserId", rawUser.UserId);
return _users.Find(filter).FirstOrDefaultAsync();
}
}

+ abp vnext

我们不需要区分以上代码场合,在Controller或者Application 服务中使用ICurrentUser接口拿到登录用户。

旁白

个人认为,ASP.NET Core身份认证的源代码, 基于现实认知提炼而来,让我们惊叹于框架代码的的简洁精炼、层次分明。

基于声明的访问控制已成标准,ASP.NET Core/abp vnext 均提供了完善的支持。

最新文章

  1. Android图片缓存之初识Glide
  2. Spring AOP 5种通知与java动态代理
  3. Android线程消息通信(一)
  4. 添加IFrame导致内存溢出的解决过程(IE浏览器,目前发现了原因,还未解决)
  5. linux记录登录ip方法
  6. 图片处理 Pillow
  7. Tomcat部署web应用的三种方式
  8. StreamCQL
  9. 转:ORACLE制造方法的比较
  10. saiku
  11. C# 各版本更新简介
  12. sha1() 函数
  13. 【评分】集美大学软件工程1413班工程项目管理个人作业2——APP案例分析
  14. Jmeter响应数据中文乱码
  15. 课程回顾-Convolutional Neural Networks
  16. java -version 问题 : C:\ProgramData\Oracle\Java\javapath;
  17. Text Justification leetcode java
  18. thinkphp结合layui上传图片
  19. 9 jmeter之检查点
  20. 程序员教程-9章-C程序设计

热门文章

  1. Pyqt QImage 与 np array 转换方法
  2. 从后端到前端之Vue(六)表单组件
  3. python爬虫--看看虎牙女主播中谁颜值最高
  4. Mono生命周期小实验
  5. 剑指 Offer 56 - I. 数组中数字出现的次数
  6. IDEA项目左侧目录看不到target
  7. Java字符串的常用方法
  8. node.js之koa安装
  9. Fragment时长统计那些事
  10. VMware参数disk.EnableUUID生效扫描不出来UUID