了解 Mvc 核心身份

Understanding Mvc Core Identity

我一直在努力寻找一个解释,但关于身份究竟如何与 mvc 核心一起工作的解释相当简短。我找到了很多关于如何实施它的指南,我已经找到了,而且一切都很好,但我想至少在一个较高的层次上理解它。

我目前的理解是,当用户通过其凭据时,身份库将颁发一个令牌,该令牌将写入浏览器的 cookie。现在,所有进一步的请求都将根据该浏览器 cookie 识别用户。但是,我似乎无法找到过去的解释。为什么这是安全的,为什么我不能窃取那个 cookie 并将其据为己有?我知道还有更多,可能我理解错了上面的部分。

无论如何,我要么在寻找有关其工作原理的高级解释,要么在寻找可以深入研究细节的好参考。

how exactly identity works with mvc core.

正如@Chris Pratt 所说,您所说的是安全子系统。既然你说的是cookie,那我就以cookie的认证方案为例

内置安全性主要存在于 4 个项目中:

  • HttpAbstractions:核心接口和类,如认证方案、认证处理程序、认证票证等。
  • Security:认证中间件、cookie认证、JWT Bearer认证、OAuth2.0认证(Google/Facebook/Microsoft/...)等
  • Identity : 一个名为 "Identity" 的脚手架项目,有助于管理 user/roles/claims/etc.
  • DataProtection:数据保护 APIs 用于保护和取消保护数据。你可以把它当作一个API来加解密

了解身份验证工作原理的切入点是 AuthenticationMiddleware。如果可能,此中间件将尝试对每个请求进行身份验证:

    public async Task Invoke(HttpContext context)
    {
        // ...

        // Give any IAuthenticationRequestHandler schemes a chance to handle the request
        var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
        foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
        {
            var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
            if (handler != null && await handler.HandleRequestAsync())
            {
                return;
            }
        }

        // Use the default scheme to authenticate request
        var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
        if (defaultAuthenticate != null)
        {
            var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
            if (result?.Principal != null)
            {
                context.User = result.Principal;
            }
        }

        await _next(context);
    }

通常,此中间件先于其他中间件运行 middlewares/mvc 因此您可以根据需要拦截请求。

当您想在不登录的情况下访问受 [Authorize] 保护的 url 时,它会要求您通过某种方案登录。您可以根据需要配置您的服务使用不同的方案,例如 Jwt Bearer、cookie 等。

如果您使用的是 cookie 方案, CookieAuthenticationHandler 会做繁重的工作:

  • Signin:当您认为您已经验证了用户主体时,将发出一个新的 cookie。
  • Authenticate: 验证客户端发送的cookie
  • Signout : 删除 cookie

注意所有这些都是由 Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler 完成的,即 aspnet/Security 中定义的处理程序,而不是 aspnet/Identity.

why can't I steal that cookie and use it as my own?

  1. 当然你可以偷别人的cookie据为己有。实际上,如果 Alice 的 cookie 被 Bob 窃取(假设通过 XSSsniffering),Bob 将被视为 Alice。 ASP.NET 核心(和其他技术,如 PHP/Python/Java)无法阻止这种情况,要防止窃取还有很多工作要做:

    • 该网站应使用 HTTPS 而不是 HTTP
    • <><img onclick='javascript:'等字符进行编码,防止XSS
    • ...
  2. 此外,有时您不需要偷别人的 cookie。通过 CSRF,您只需 "borrow" 他的 cookie。

Why is this safe

通常,即使理论上可以窃取某人的 cookie 或借用某人的 cookie,但只有当您以错误的方式开发应用程序或以不安全的方式部署它们时才会发生。

另一件事是您很难在客户端伪造 cookie。