65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET Core Identity 入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (11投票s)

2017 年 12 月 5 日

CPOL

3分钟阅读

viewsIcon

35455

研究 ASP.NET Core Identity 的工作原理

引言

这将是一系列关于 ASP.NET Core Identity 的文章,每篇文章都有一个包含完整代码示例的 github 仓库。在第一篇文章中,我们将研究基于声明的身份验证是什么,ASP.NET Core Identity 如何实现它,以及整个身份验证系统如何工作。

ASP.NET Core Identity 是 .NET Core 自带的新的会员系统。与之前的版本不同,它使用基于声明的身份验证,这是与之前版本的 ASP.NET Identity 最大的变化之一。

基于声明的身份验证

在开始探索身份验证系统之前,我们将花一些时间来理解基于声明的身份验证。

让我们考虑一个场景,大学生 Bob 去银行开户。现在银行经理想看一些证明 Bob 身份的文件。Bob 给了他的驾驶执照,上面有他的姓名、出生日期和地址。

现在 Bob 还想申请银行只提供给学生的折扣。经理再次要求一些证明 Bob 是学生的文件。这次 Bob 给了他的学生证,上面有他的姓名、大学名称、院系名称和学号。

这个真实生活场景可以用来类比解释基于声明的身份验证。这里 Bob 是使用基于声明的身份验证的用户。他使用两个身份(一个用户可以有多个身份) - 驾驶执照和学生证。身份有附加的声明 - 姓名、出生日期、学号等。

在 ASP.NET Core Identity 中的实现

ASP.NET Core 的一个优点是它是开源的,如果需要,我们可以研究源代码以了解它的工作原理。ASP.NET Core Identity 源代码可以在这个 github 仓库中找到 - https://github.com/aspnet/Identity

在当前 ASP.NET Core 的实现中,UserClaimsPrincipal 类型,它实现了 IPrincipalClaimsPrincipal 类在 System.Security.Claims 命名空间下实现。

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

从实现中,我们可以看到 ClaimsPrincipal 类具有 Identities 属性,该属性返回 ClaimsIdentity 的集合。这意味着一个用户可以有多个身份。

还有另一个属性 Identity。不要让它混淆你,它返回与此声明主体关联的主声明身份。

另一个重要的属性是 Claims,它返回一个集合,其中包含来自与此声明主体关联的所有声明身份的所有声明。

现在让我们看一下 ClaimsIdentity 类。

public class ClaimsIdentity : IIdentity
{
    ........... 
    ........... 
    public virtual string AuthenticationType { get; }
    public virtual string Name { get; }
    public virtual bool IsAuthenticated { get; }
    public virtual IEnumerable<Claim> Claims { get; }
<claim>    public virtual IEnumerable<Claim> FindAll(Predicate<Claim> match);<claim><claim>
    public virtual Claim FindFirst(string type);
    public virtual bool HasClaim(string type, string value);
    ........... 
    ........... 
}

AuthenticationType 返回类型,它可以是 Basic、Windows、Cookie 等。

Claims 属性返回与此身份关联的声明的集合。

所以现在如果我们尝试将 Bob 的例子与这些类进行映射,它将看起来像这样

与 ASP.NET Core Identity 交互

ASP.NET Core Identity 实现了 一些 API(SignInManagerUserManagerRoleManager 等),简化了与身份验证对象的交互。在 ASP.NET Core 项目中工作时,依赖注入将为这些类提供对象,以便我们可以使用它们。

例如,SignInManager 实现了以下 public 方法来登录用户

public virtual async Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, 
string authenticationMethod = null)
{
	var userPrincipal = await CreateUserPrincipalAsync(user);
	if (authenticationMethod != null)
	{
		userPrincipal.Identities.First().AddClaim(new Claim
               (ClaimTypes.AuthenticationMethod, authenticationMethod));
	}
	await Context.SignInAsync(IdentityConstants.ApplicationScheme,
		userPrincipal,
		authenticationProperties ?? new AuthenticationProperties());
}

如果您想了解登录、注销和其他流程如何工作,我建议您下载并查看源代码。

在接下来的文章中,我将从一个空项目开始,逐步添加不同的功能,如登录、注销、令牌生成等。

© . All rights reserved.