HTML5技术

ASP.NET Core 认证与授权[2]:Cookie认证 - 雨の夜

字号+ 作者:H5之家 来源:H5之家 2017-09-29 16:04 我要评论( )

ASP.NET Core 认证与授权[2]:Cookie认证 由于HTTP协议是无状态的,但对于认证来说,必然要通过一种机制来保存用户状态,而最常用,也最简单的就是Cookie了,它由浏览器自动保存并在发送请求时自动附加到请求头中。尽管在现代Web应用中,Cookie已略显笨重,但

ASP.NET Core 认证与授权[2]:Cookie认证

由于HTTP协议是无状态的,但对于认证来说,必然要通过一种机制来保存用户状态,而最常用,也最简单的就是Cookie了,它由浏览器自动保存并在发送请求时自动附加到请求头中。尽管在现代Web应用中,Cookie已略显笨重,但它依然是最为重要的用户身份保存方式。在 上一章 中整体的介绍了一下 ASP.NET Core 中的认证流程,而未提及具体的实现方式,较为抽象,那本章就通过一个完整的示例,以及对其原理的解剖,来详细介绍一下Cookie认证,希望能帮助大家对 ASP.NET Core 认证系统有一个更深入的了解。

目录

示例

我们从零开始,一步一步来创建一个完整的 ASP.NET Core Cookie认证的详细示例。

创建项目

我们首先创建一个空的 .NET Core 2.0 Web 项目:

create_project

在创建的空项目中,默认具有如下引用:

Microsoft.AspNetCore.All 是 ASP.NET Core 的全家桶,包含 Mvc, EFCore, Identity, NodeService, AzureAppServe 等等,并集成到了 .NET Core SDK 当中,个人感觉略坑,有违 .NET Core 轻量模块化的理念,虽然使用看似更加方便了,却也让我们变得更加傻瓜化。在本文中为了更好的演示,就移除掉 Microsoft.AspNetCore.All 的引用,然后手动安装需要的Nuget包,当然,你可以不这么做,并略过此小节。

在本章中,会用到以下几个项目中的Nuget包:

我们使用 DotNet CLI 来安装Nuget包:

dotnet add package Microsoft.AspNetCore.Hosting --version 2.0.0 dotnet add package Microsoft.AspNetCore.Server.Kestrel --version 2.0.0 dotnet add package Microsoft.Extensions.Logging.Console --version 2.0.0 dotnet add package Microsoft.AspNetCore.Authentication.Cookies --version 2.0.0

由于WebHost.CreateDefaultBuilder包含在Microsoft.AspNetCore.All中,需要对Program做如下修改:

public static IWebHost BuildWebHost(string[] args) => new WebHostBuilder() .UseKestrel() .UseUrls(":5000") .UseContentRoot(Directory.GetCurrentDirectory()) .ConfigureLogging((hostingContext, logging) => { logging.AddConsole(); }) .UseStartup<Startup>() .Build();

如上,我们使用Kestrel服务器,监听5000端口,并将日志打印到控制台,需要注意的是我们并没有使用UseIISIntegration,因此不支持在IIS下运行,需要使用控制台的方式来运行,修改Properties/launchSettings.json文件:

如上,将IIS的相关配置删除掉,只保留控制台的启动配置,然后在Starup文件的Configure方法中添加如下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); }

最后按下F5,启动程序,在浏览器中访问访问::5000/,输出:

Hello World! 配置Cookie认证

在 ASP.NET Core 中,有一个非常重要的依赖注入系统,它贯穿于所有项目中。对于认证系统,同样要先进行注册:

public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(options => { // 在这里可以根据需要添加一些Cookie认证相关的配置,在本次示例中使用默认值就可以了。 }); }

如上,我们只配置了DefaultScheme,这样,DefaultSignInScheme, DefaultSignOutScheme, DefaultChallengeScheme, DefaultForbidScheme 等都会使用该 Scheme 作为默认值。

AddCookie 用来注册 CookieAuthenticationHandler,由它来完成身份认证的主要逻辑。

在注册完服务之后,接下来便是注册中间件,在 ASP.NET Core 中都是这个套路:

public void Configure(IApplicationBuilder app) { app.UseAuthentication(); }

如上,使用UseAuthentication方法注册了AuthenticationMiddleware中间件,它会负责调用对应的Handler,在上一章中有详细的介绍。

准备工作

既然是身份认证,那首先要有用户,我们在这里模拟一个用户仓储,用来实现用户登录时的用户名和密码的检查。

定义用户类:

public class User { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public string PhoneNumber { get; set; } public string Password { get; set; } public int Age { get; set; } }

定义用户仓储:

public class UserStore { private static List<User> _users = new List<User>() { new User { Id=1, Name="alice", Password="alice", Email="alice@gmail.com", PhoneNumber="18800000001" }, new User { Id=1, Name="bob", Password="bob", Email="bob@gmail.com", PhoneNumber="18800000002" } }; public User FindUser(string userName, string password) { return _users.FirstOrDefault(_ => _.Name == userName && _.Password == password); } }

将UserStore注册到DI系统中:

public void ConfigureServices(IServiceCollection services) { ... services.AddSingleton<UserStore>(); }

由于我们并没有使用MVC,而使用字符串拼接的形式返回HTML较为费劲,在这里定义几个生成HTML的扩展方法:

public static class HttpResponseExtensions { public static async Task WriteHtmlAsync(this HttpResponse response, Func<HttpResponse, Task> writeContent) { var bootstrap = "<link rel=\"stylesheet\" href=\"https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u\" crossorigin=\"anonymous\">"; response.ContentType = "text/html"; await response.WriteAsync($"<!DOCTYPE html><html lang=\"zh-CN\"><head><meta charset=\"UTF-8\">{bootstrap}</head><body><div class=\"container\">"); await writeContent(response); await response.WriteAsync("</div></body></html>"); } public static async Task WriteTableHeader(this HttpResponse response, IEnumerable<string> columns, IEnumerable<IEnumerable<string>> data) { await response.WriteAsync("<table class=\"table table-condensed\">"); await response.WriteAsync("<tr>"); foreach (var column in columns) { await response.WriteAsync($"<th>{HtmlEncode(column)}</th>"); } await response.WriteAsync("</tr>"); foreach (var row in data) { await response.WriteAsync("<tr>"); foreach (var column in row) { await response.WriteAsync($"<td>{HtmlEncode(column)}</td>"); } await response.WriteAsync("</tr>"); } await response.WriteAsync("</table>"); } public static string HtmlEncode(string content) => string.IsNullOrEmpty(content) ? string.Empty : HtmlEncoder.Default.Encode(content); } 认证流程

接下来,便可以在我们的应用程序中愉快的使用认证系统了。在本文中只是最简单的演示,便不使用MVC了,而是在Configure中通过中间件的形式来实现。

登录

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

    ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解 - 行动派Xdpie

    2017-09-15 17:05

  • Entity Framework Core Like 查询揭秘 - Sweet-Tang

    Entity Framework Core Like 查询揭秘 - Sweet-Tang

    2017-09-13 12:05

  • ASP.NET Core 运行原理解剖[5]:Authentication - 雨の夜

    ASP.NET Core 运行原理解剖[5]:Authentication - 雨の夜

    2017-09-11 11:16

  • 【ASP.NET MVC】View与Controller之间传递数据 - Alan_beijing

    【ASP.NET MVC】View与Controller之间传递数据 - Alan_beijing

    2017-09-10 08:02

网友点评
h