美文网首页
ASP.NET Core身份验证简介

ASP.NET Core身份验证简介

作者: 灭蒙鸟 | 来源:发表于2019-12-23 22:37 被阅读0次

    这是有关ASP.NET Core中的身份验证和授权的一系列文章中的第一篇。在本文中,我将大致讨论身份验证以及ASP.NET Core中基于声明的身份验证的工作方式。

    身份验证和授权之间的区别

    首先,我们应该弄清这两个依赖的安全方面之间的区别。简单的答案是,认证是确定的过程中你是谁,而授权围绕着你被允许做什么,即权限。显然,在确定允许用户做什么之前,您需要知道他们是谁,因此,在需要授权时,还必须首先以某种方式对用户进行身份验证。

    ASP.NET Core中的身份验证

    与身份相关的基本属性在ASP.NET Core中并未真正更改-尽管它们不同,但它们通常应为ASP.NET开发人员所熟悉。例如,在ASP.NET 4.x中,有一个名为Useron 的属性HttpContext,该属性的类型为IPrincipal,表示请求的当前用户。在ASP.NET核心有一个类似的属性命名User,区别在于这种属性的类型的ClaimsPrincipal,它实现了IPrincipal

    ClaimsPrincipal与ASP.NET 4.x相比,使用此举凸显了ASP.NET Core中身份验证工作方式的根本变化。以前,授权通常是基于角色的,因此用户可能属于一个或多个角色,并且您应用的不同部分可能要求用户具有特定角色才能访问它。在ASP.NET Core中,仍可以使用这种基于角色的授权,但这主要是出于向后兼容性的原因。他们真正希望您采用的方法是基于声明的身份验证。

    基于声明的身份验证

    基于声明的身份验证的概念在您初次使用时可能会有些混乱,但实际上,它可能与您已经在使用的方法非常相似。您可以将声明视为对特定身份的声明或属性。该语句包含一个名称和一个值。例如,您可能有一个DateOfBirth索赔,FirstName索赔,EmailAddress索赔或IsVIP索赔。请注意,这些陈述是关于身份或身份,而不是他们可以做什么

    身份本身代表一个声明,该声明可能具有许多与之相关的声明。例如,考虑驾驶执照。这是一个包含了一些索赔的单一身份- ,FirstName,,LastName以及车辆允许您的车程。您的护照将是具有不同索偿要求的不同身份。DateOfBirth``Address

    因此,让我们在ASP.NET Core的上下文中进行查看。ASP.NET Core中的身份是一个ClaimsIdentity。该类的简化版本可能看起来像这样(实际的类要大很多!):

    public class ClaimsIdentity: IIdentity
    {
        public string AuthenticationType { get; }
        public bool IsAuthenticated { get; }
        public IEnumerable<Claim> Claims { get; }
    
        public Claim FindFirst(string type) { /*...*/ }
        public Claim HasClaim(string type, string value) { /*...*/ }
    }
    
    

    我已经在此概述中显示了主要属性,包括Claims由与身份相关的所有声明组成。有很多实用的方法可用于处理Claims,我在这里展示了其中的两种。这些在您进行授权时非常有用,并且您试图确定某个特定的身份是否对Claim您感兴趣。

    AuthenticationType物业是不言自明的。在我们以前实际的例子,这可能是字符串PassportDriversLicense,但在ASP.NET它更可能是CookiesBearerGoogle等,这是仅仅是被用来验证用户,并确定与身份相关的索赔的方法。

    最后,该属性IsAuthenticated指示身份是否已通过身份验证。这似乎是多余的-如果未通过身份验证,您如何拥有声明的身份?一种情况是您允许访客用户访问您的网站,例如购物车。您仍然具有与用户关联的身份,并且该身份可能仍具有与之关联的声明,但是它们不会被认证。这是要记住的重要区别。

    作为补充,在ASP.NET Core中,如果您在构造函数中创建ClaimsIdentity并提供AuthenticationTypeIsAuthenticated则始终为true。因此,经过身份验证的用户必须始终具有AuthenticationType,并且,相反,您不能拥有具有的未经身份验证的用户AuthenticationType

    多重身份

    希望在这一点上您对主张及其与身份的关系有概念上的了解。我在本节的开头说过,Useron 的属性HttpContext是a ClaimsPrincipal,而不是a ClaimsIdentity,因此让我们看一下它的简化版本:

    public class ClaimsPrincipal :IPrincipal
    {
        public IIdentity Identity { get; }
        public IEnumerable<ClaimsIdentity> Identities { get; }
        public IEnumerable<Claim> Claims { get; }
    
        public bool IsInRole(string role) { /*...*/ }
        public Claim FindFirst(string type) { /*...*/ }
        public Claim HasClaim(string type, string value) { /*...*/ }
    }
    
    

    从此类中获取的重要一点是,有一个Identities返回的属性IEnumerable<ClaimsIdentity>。因此,一个ClaimsPrincipal可以包含多个IdentitiesIdentity为了实现IPrincipal接口,还有一个属性-在.NET Core中,它仅选择.NET Core中的第一个标识Identities

    回到我们之前的护照和驾驶执照示例,实际上可以使用多种身份-这些文件都是身份的形式,每种形式都包含许多索偿要求。在这种情况下,是主体,并且您有两种形式的身份。当您拥有这两个身份时,作为委托人,您将继承所有身份的所有主张。

    考虑另一个实际的例子-您正在乘飞机。首先,将在预订柜台要求您证明对您的索赔FirstNameLastName等等。幸运的是,您记得您的护照,该护照可以验证这些索赔,因此您会收到登机牌,并且正在前往下一步。

    出于安全考虑,您需要证明您预订了航班。这次,您需要携带的另一种身份证明,即具有FlightNumber要求的登机牌,因此您可以继续前进。

    最后,通过安检后,您便进入了贵宾休息室,并被要求在VIP Number索赔中证明您的贵宾身份。这可以是VIP卡的形式,这是另一种身份形式,可以验证请求的索赔。如果您没有卡,则无法提出请求的索偿,将无法访问您,因此将被要求离开并停止现场演出。

    在机场的多个身份和索偿的图像

    同样,这里的要点是,委托人可以具有多个身份,这些身份可以具有多个声明,并且ClaimsPrincipal继承其的所有声明Identities

    如前所述,基于角色的授权主要是出于向后兼容的原因,因此,IsInRole如果您遵循ASP.NET Core中强调的基于声明的身份验证,通常将不需要该方法。在后台,这也只是使用声明实现,声明类型默认为RoleClaimTypeClaimType.Role

    再次考虑ASP.NET Core,可以使用多个标识和声明来保护应用程序的不同部分,就像在机场一样。例如,您可以使用用户名和密码登录,并根据与之关联的身份被授予一组声明,从而可以浏览该网站。但是请说您的应用程序中有一个特别敏感的部分,您想进一步保护它。这可能需要您提供其他身份以及其他相关声明,例如,通过使用两因素身份验证,或者要求您重新输入密码。这将允许当前原则具有多个标识,并假定所有提供的标识的主张。

    创建一个新的校长

    因此,现在我们已经看到了主体在ASP.NET Core中的工作方式,我们将如何实际创建主体?一个简单的示例,例如您在正常的网页登录中可能看到的,可能包含类似于以下内容的代码

    public async Task<IActionResult> Login(string returnUrl = null)
    {
        const string Issuer = "https://gov.uk";
    
        var claims = new List<Claim> {
            new Claim(ClaimTypes.Name, "Andrew", ClaimValueTypes.String, Issuer),
            new Claim(ClaimTypes.Surname, "Lock", ClaimValueTypes.String, Issuer),
            new Claim(ClaimTypes.Country, "UK", ClaimValueTypes.String, Issuer),
            new Claim("ChildhoodHero", "Ronnie James Dio", ClaimValueTypes.String)
        };
    
        var userIdentity = new ClaimsIdentity(claims, "Passport");
    
        var userPrincipal = new ClaimsPrincipal(userIdentity);
    
        await HttpContext.Authentication.SignInAsync("Cookie", userPrincipal,
            new AuthenticationProperties
            {
                ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
                IsPersistent = false,
                AllowRefresh = false
            });
    
        return RedirectToLocal(returnUrl);
    }
    
    

    该方法当前将索偿硬编码到其中,但是显然您将从数据库或其他来源获取索偿值。我们要做的第一件事是建立一个声明列表,为每个声明填充一个名称字符串,其值字符串以及可选IssuerClaimValueType字段。的ClaimType类是其暴露了一些常见类型的权利要求的一个帮手。例如http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name,每一个都是一个url ,但是您不必使用url,如最后添加的声明所示。

    建立索赔之后,您可以创建一个new ClaimsIdentity,传入您的索赔列表,并指定AuthenticationType(以确保您的身份具有IsAuthenticated=true)。最后,你可以创建一个新的ClaimsPrincipal使用您的身份和登录用户。在这种情况下,我们说的是AuthenticationManager使用"Cookie"认证处理,这是我们必须配置为我们的中间件管道的一部分。

    摘要

    在这篇文章中,我描述了基于声明的身份验证如何工作以及如何将其应用于ASP.NET Core。在下一篇文章中,我将介绍身份验证过程的下一阶段-cookie中间件实际上是如何使用提供的主体登录您的。随后的文章将介绍如何使用多个身份验证处理程序,授权的工作方式以及ASP.NET Core Identity如何将它们全部绑定在一起。

    相关文章

      网友评论

          本文标题:ASP.NET Core身份验证简介

          本文链接:https://www.haomeiwen.com/subject/dhstwctx.html