一、深入解读 ASP.NET Core 身份认证过程

原文地址:点这 今天我们乘胜追击:聊一聊ASP.NET Core 中的身份验证。 身份验证是确定用户身份的过程。 授权是确定用户是否有权访问资源的过程。

1. 万变不离其宗

显而易见,一个常规的身份认证用例包括两部分:
① 对用户进行身份验证
② 在未经身份验证的用户试图访问受限资源时作出反应 已注册的身份验证处理程序及其配置选项被称为“方案”,方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。 我们口头上常说的:
基于cookie认证方案,若认证成功,go on,若认证失败则跳转回登录页面;
基于基本身份认证(BA)方案,若认证成功,go on,若认证失败则给浏览器返回WWW-Authenticate标头, 浏览器会再次弹出认证窗口。

2. ASP.NET Core认证原理

在 ASP.NET Core 中,身份验证由IAuthenticationService负责,身份验证服务会调用已注册的身份验证处理程序来完成与身份验证相关的操作, 整个验证过程由认证中间件来串联。 一图以蔽之:
.NET Core--身份认证 - 图1 其中有几个关键步骤

①. 认证处理程序

可结合方案Scheme中的配置项AuthenticationSchemeOptions编写认证处理程序。 基于Cookie的认证方案可在Options项中可指定登录地址,
基于基本身份的认证方案可在Options项中指定用户名/密码;

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

.NET Core--身份认证 - 图2

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

挑战/质询 (对未认证的用户做出的反应): 401 Unauthorized + 例如返回登录页面

禁止(对已认证,但对特定资源无权访问做出的反应) :403 Forbidden + 例如返回提示字符串 以上均为服务注册过程

③. 收到请求,认证中间件使用IAuthenticationService对HttpContext按照要求的scheme进行认证,

实际内部会调用第2步编写的认证处理程序。
.NET Core--身份认证 - 图3

以上认证原理,之前有一个近身实战: ASP.NET Core 实现基本身份验证。
源代码如下: https://www.cnblogs.com/JulianHuang/p/10345365.html ### 3. ASP.NET Core获取当前用户 > 基于声明的访问控制, 我们会在HttpContext.User属性存储身份信息。 > csharp 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属性/参数, 可直接使用。
  1. var user = User?.Identity?.Name ?? "N/A";
  2. //或者
  3. var user = HttpContext.User.Identity.Name;

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

这个时候,服务是作为请求处理中的一个环节,并没有直接可用的HttpContext。
ASP.NET Core 提供了IHttpContextAccessor类能够注入此次请求中的HttpContext对象(依赖注入框架的作用)。
  1. // 下面的用户实体类,需要获取当前登录用户,借助IHttpContextAccessor注入httpContext
  2. public class UserEntityService : IUserEntityService
  3. {
  4. private IHttpContextAccessor _accessor;
  5. private readonly IMongoCollection<UserProfile> _users;
  6. public UserEntityService(IHttpContextAccessor accessor, IDefaultMongoDatabaseProvider databaseProvider)
  7. {
  8. _accessor = accessor;
  9. _users = databaseProvider.GetCollection<UserProfile>(CollectionNames.UserProfiles);
  10. }
  11. public Task<UserProfile> GetCurrentUserAsync()
  12. {
  13. var rawUser = this._accessor.HttpContext.User();
  14. if (rawUser == null)
  15. {
  16. return null;
  17. }
  18. var filter = Builders<UserProfile>.Filter.Eq("UserId", rawUser.UserId);
  19. return _users.Find(filter).FirstOrDefaultAsync();
  20. }
  21. }
我们不需要区分以上代码场合,在Controller或者Application 服务中使用ICurrentUser接口拿到登录用户。

二、.Net Core使用windows身份验证

官方文档 已经介绍了多种服务器配置windos身份验证,如果觉得看的不是很明白的可以继续往下看。

框架.NET Core API

我们需要做的第一件事就是确保我们的应用程序以Windows身份验证运行。由于我使用VS生成了项目并提供了Docker支持,因此我不得不做一些您可能不需要做的事情。

1. 启用Windows身份验证

我要做的第一件事是将调试启动器从Docker切换到IIS Express。

.NET Core--身份认证 - 图4

2. 切换默认启动

接下来,我需要打开我的launchSettings.json“windowsAuthentication”: true在iisSettings下进行设置。

启用Windows身份验证

.NET Core--身份认证 - 图5

好吧,让我们稍等一秒钟。为了使Windows身份验证起作用,您将需要在IISIIS Express中进行托管。您也可以使用KestrelHTTP.sys托管来完成此操作,但出于本文的方便,让我们集中讨论IIS Express。如果您想使它在Docker和/或Linux上运行,您将要使用Kestrel

我们的应用程序现在可以与Windows身份验证一起使用了,但是如果我们现在启动它,它仍然不会使用。我们还有很多工作要做。

3. 配置Windows身份验证

现在我们已经设置了API以通过IIS使用Windows身份验证,我们需要使API本身意识到这一点。为此,我们需要对进行一些调整Startup.cs。MSDN上有文档,但我们也可以在这里进行阅读。

您需要做的第一件事是services.AddAuthentication(IISDefaults.AuthenticationScheme);在您的ConfigureServices方法中添加任何位置。这利用了Microsoft.AspNetCore.Server.IISIntegration命名空间。

.NET Core--身份认证 - 图6

4. 添加Windows身份验证

接下来,您需要配置Windows身份验证需要保护哪些控制器或动作。顺便说一下,这就是为什么我们“anonymousAuthentication”: true独自留在launchSettings.json。这里的一个用例是,如果您使用的是Swagger,并且希望匿名访问文档并且仅保护API本身。

在我的用例中,我假装我希望所有API控制器都需要身份验证。鉴于此,我创建了一个WebControllerBase.cs,并用[Authorize]属性对其进行了装饰。请注意,您可以改为用[Authorize]标记每个控制器。WebControllerBase,将[Authorize]标记为需要身份验证。

接下来,只需让我们现有的控制器和新控制器继承自WebControllerBase而不是即可ControllerBase

.NET Core--身份认证 - 图7

现在,我们现有的控制器继承自WebControllerBase

在网络上的其他示例中,您可能会看到人们说您需要添加app.UseAuthentication()Configure(IApplicationBuilder app, IWebHostEnvironment env)方法。如果仅针对IIS / IIS Express,则不会。也就是说,添加它不会伤害您。我不会判断你是否愿意。但是我的源代码有它。

5. 测试一下!

现在,我们可以对其进行测试了。在WeatherForecastController顶部打一个断点:以调试模式获取并运行Web应用程序。达到断点时,添加监视HttpContext.User,并向下监测.Identity.Name。(可选)只需在方法顶部添加此行:var user = HttpContext.User?.Identity?.Name ?? “N/A”;并查看结果。您的应用程序现在正在报告您当前的Windows用户名。

代码示例:

  1. var empId = HttpContext.User.Identity.Name;
  2. var user = User?.Identity?.Name ?? "N/A";
  3. var zzz = Environment.UserName;
  4. var name1 = WindowsIdentity.GetCurrent().Name;

具体哪个方法可以获取需要你自己测试喔。