HTML5技术

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

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

首先,我们定义一个登录的页面以及登录成功后身体令牌的发放: app.Map(/Account/Login, builder = builder.Run(async context ={if (context.Request.Method == GET){await context.Response.WriteHtmlAsync(async

首先,我们定义一个登录的页面以及登录成功后身体令牌的发放:

app.Map("/Account/Login", builder => builder.Run(async context => { if (context.Request.Method == "GET") { await context.Response.WriteHtmlAsync(async res => { await res.WriteAsync($"<form method=\"post\">"); await res.WriteAsync($"<input type=\"hidden\" name=\"returnUrl\" value=\"{HttpResponseExtensions.HtmlEncode(context.Request.Query["ReturnUrl"])}\"/>"); await res.WriteAsync($"<div class=\"form-group\"><label>用户名:<input type=\"text\" name=\"userName\" class=\"form-control\"></label></div>"); await res.WriteAsync($"<div class=\"form-group\"><label>密码:<input type=\"password\" name=\"password\" class=\"form-control\"></label></div>"); await res.WriteAsync($"<button type=\"submit\" class=\"btn btn-default\">登录</button>"); await res.WriteAsync($"</form>"); }); } else { var userStore = context.RequestServices.GetService<UserStore>(); var user = userStore.FindUser(context.Request.Form["userName"], context.Request.Form["password"]); if (user == null) { await context.Response.WriteHtmlAsync(async res => { await res.WriteAsync($"<h1>用户名或密码错误。</h1>"); await res.WriteAsync("<a class=\"btn btn-default\" href=\"/Account/Login\">返回</a>"); }); } else { var claimIdentity = new ClaimsIdentity("Cookie"); claimIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); claimIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Name)); claimIdentity.AddClaim(new Claim(ClaimTypes.Email, user.Email)); claimIdentity.AddClaim(new Claim(ClaimTypes.MobilePhone, user.PhoneNumber)); claimIdentity.AddClaim(new Claim(ClaimTypes.DateOfBirth, user.Birthday.ToString())); var claimsPrincipal = new ClaimsPrincipal(claimIdentity); // 在上面注册AddAuthentication时,指定了默认的Scheme,在这里便可以不再指定Scheme。 await context.SignInAsync(claimsPrincipal); if (string.IsNullOrEmpty(context.Request.Form["ReturnUrl"])) context.Response.Redirect("/"); else context.Response.Redirect(context.Request.Form["ReturnUrl"]); } } }));

如上,我们在Get请求中返回登录页面,在Post请求中验证用户名密码,匹配成功后,创建用户Claim, ClaimsIdentity, ClaimsPrincipal 最终通过SignInAsync方法将用户身份写入到响应Cookie中,完成身份令牌的发放。

授权

我们在登录中间件后面添加一个自定义的授权中间件,用来禁用匿名用户的访问:

app.UseAuthorize();

UseAuthorize的实现很简单,就是判断用户是否已通过认证,并跳过对首页的验证:

public static IApplicationBuilder UseAuthorize(this IApplicationBuilder app) { return app.Use(async (context, next) => { if (context.Request.Path == "/") { await next(); } else { var user = context.User; if (user?.Identity?.IsAuthenticated ?? false) { await next(); } else { await context.ChallengeAsync(); } } }); }

其实上面的实现和我们在MVC5中常用的[Authorize]特性非常相似。

个人信息

再定义一个认证后才能访问的页面,并把当前登录用户的信息展示出来:

app.Map("/profile", builder => builder.Run(async context => { await context.Response.WriteHtmlAsync(async res => { await res.WriteAsync($"<h1>你好,当前登录用户: {HttpResponseExtensions.HtmlEncode(context.User.Identity.Name)}</h1>"); await res.WriteAsync("<a class=\"btn btn-default\" href=\"/Account/Logout\">退出</a>"); await res.WriteAsync($"<h2>AuthenticationType:{context.User.Identity.AuthenticationType}</h2>"); await res.WriteAsync("<h2>Claims:</h2>"); await res.WriteTableHeader(new string[] { "Claim Type", "Value" }, context.User.Claims.Select(c => new string[] { c.Type, c.Value })); }); })); 退出

 

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

网友点评
<