前言

本示例完全是基于 ASP.NET Core 3.0。本文核心是要理解 Claim, ClaimsIdentity, ClaimsPrincipal,读者如果有疑问,可以参考文章 理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文

代码

项目文件 csproj 的配置

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
</ItemGroup>
</Project>

Program.cs

注意: ASP.NET Core 3.0 的配置和 v2.2 稍微有一点不同。

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

Startup

注意:不管是 ConfigureServices 方法,还是 Configure 方法,配置的顺序至关重要,有可能明明配置了 XX,运行时却总是无效。比如笔者实验时,把 app.UseAuthentication(); 写到了 app.UseRouting() 前面,结果导致运行时,标记在 Action 方法上面的 [Authorize] 总是无效,结果发现是注册的顺序搞错了,大家一定要注意这点。

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) // Sets the default scheme to cookies
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.AccessDeniedPath = "/account/denied";
options.LoginPath = "/account/login";
}); services.AddControllersWithViews(); // Example of how to customize a particular instance of cookie options and
// is able to also use other services.
// will override CookieAuthenticationOptions, such as LoginPath => "/account/hello"
//services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, ConfigureMyCookie>();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseDeveloperExceptionPage(); // Temp Open
//app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); // Remember to put it behind app.UseRouting()
app.UseAuthorization(); // Remember to put it behind app.UseRouting() app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}

HomeController

在需要授权才能访问的 Action 方法上标记  [Authorize]

public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
} public IActionResult Index()
{
return View();
} [Authorize]
public IActionResult MyClaims()
{
return View();
} public IActionResult Privacy()
{
return View();
}
}

_Layout.cshtml

在这里面,可以通过 @User.Identity.IsAuthenticated 来判断用户是否已经进行了授权,如果已经授权,则显示 “Logout” 链接。

<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="MyClaims">My Claims</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy_@(User.Identity.IsAuthenticated)</a>
</li>
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Logout">Logout</a>
</li>
}

AccountController

注意:由于之前我们在 Starup 中配置了 CookieAuthenticationOptions 类(Microsoft.AspNetCore.Authentication.Cookies. CookieAuthenticationOptions)的 options.LoginPath = "/account/login"; 这时候如果访问 /home/MyCliams 时,会自动跳转到 /account/login。

ApplicationUser

    public class ApplicationUser
{
public string Email { get; set; }
public string FullName { get; set; }
}

LoginViewModel

    public class LoginViewModel
{
public string UserName { get; set; } public string Password { get; set; }
}
    public class AccountController : Controller
{
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
} private async Task<ApplicationUser> AuthenticateUser(string email, string password)
{
// For demonstration purposes, authenticate a user
// with a static email address. Ignore the password.
// Assume that checking the database takes 500ms await Task.Delay(); //if (email == "maria.rodriguez@contoso.com")
//{
return new ApplicationUser()
{
Email = "maria.rodriguez@contoso.com",
FullName = "Maria Rodriguez"
};
//}
//else
//{
// return null;
//}
} [HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl = null)
{
if (!ModelState.IsValid)
{
return Content("validation fail");
}
var user = await AuthenticateUser(loginViewModel.UserName, loginViewModel.Password);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View();
}
ViewData["ReturnUrl"] = returnUrl; var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
}; var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme); var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed. //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie. //IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based. //IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued. //RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
}; await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties); if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return Redirect("/");
}
} public IActionResult AccessDenied(string returnUrl = null)
{
return View();
} public async Task<IActionResult> Logout()
{
#region snippet1
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
#endregion return Redirect("/");
}
}

上面的代码即包含“登录”方法,又包含登出方法。

await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);

关于 Claim, ClaimsIdentity, ClaimsPrincipal,读者如果有疑问,可以参考文章 理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

MyClaims.cshtml

@using Microsoft.AspNetCore.Authentication

<h2>HttpContext.User.Claims</h2>

<dl>
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl> <h2>AuthenticationProperties</h2> <dl>
@{
var taskAuth = await Context.AuthenticateAsync();
}
@if(taskAuth != null && taskAuth.Properties != null && taskAuth.Properties.Items != null)
{
@foreach (var prop in taskAuth.Properties.Items)
{
<dt>@prop.Key</dt>
<dd>@prop.Value</dd>
}
}
else
{
<dt>no data.</dt>
}
</dl>

运行截图

1. 没有登录的情况下

2. 登录界面

3. 登录成功

谢谢浏览!

ASP.NET Core 如何用 Cookie 来做身份验证的更多相关文章

  1. Asp.Net Core 5 REST API 使用 JWT 身份验证 - Step by Step

    翻译自 Mohamad Lawand 2021年1月22日的文章 <Asp Net Core 5 Rest API Authentication with JWT Step by Step> ...

  2. ASP.NET CORE中使用Cookie身份认证

    大家在使用ASP.NET的时候一定都用过FormsAuthentication做登录用户的身份认证,FormsAuthentication的核心就是Cookie,ASP.NET会将用户名存储在Cook ...

  3. 在ASP.NET Core 中使用Cookie中间件

    在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...

  4. 在ASP.NET Core 中使用Cookie中间件 (.net core 1.x适用)

    在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...

  5. 如何在ASP.NET Core中实现一个基础的身份认证

    注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET Core中实现一个基础的身份认证 ...

  6. [转]如何在ASP.NET Core中实现一个基础的身份认证

    本文转自:http://www.cnblogs.com/onecodeonescript/p/6015512.html 注:本文提到的代码示例下载地址> How to achieve a bas ...

  7. ASP.NET Core WebApi基于JWT实现接口授权验证

    一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...

  8. 使用ASP.NET Identity 实现WebAPI接口的Oauth身份验证

    使用ASP.NET Identity 实现WebAPI接口的Oauth身份验证   目前WEB 前后端分离的开发模式比较流行,之前做过的几个小项目也都是前后分离的模式,后端使用asp.net weba ...

  9. asp.net core 2.0 cookie的使用

    本文假设读者已经了解cookie的概念和作用,并且在传统的.net framework平台上使用过. cookie的使用方法和之前的相比也有所变化.之前是通过cookie的add.set.clear. ...

随机推荐

  1. JVM基础回顾记录(二):垃圾收集

    垃圾收集流程&HotSpot对该流程的实现方式 上一篇介绍了jvm的内存模型,本篇将介绍虚拟机中最为复杂的一部分:垃圾收集,本篇会从垃圾回收前的准备工作到后面的收集阶段的方式以及HotSpot ...

  2. ELK收集windows服务器日志笔记

    一.软件版本 1.jdk-8u211-linux-x64.rpm 2.elasticsearch-6.8.1.rpm 3.logstash-6.8.1.rpm 4.kibana-6.8.1-x86_6 ...

  3. css多余文本使用....代替

    1. 只显示单行文本,多余文本使用...代替 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 2. 显示多行文本,多余文 ...

  4. C# 调用POST请求

    public static void PostUrl_Ex(string url, string postData) { try { //对于提交内容中的中文使用UrlEncode方式编码 发送 // ...

  5. linux中rpm和yum

    一.rpm介绍 一种用于互联网下载包的打包及安装工具.它生成具有.RPM 扩展名的文件.RPM 是 RedHat Package Manager(RedHat 软件包管理工具)的缩写,类似 windo ...

  6. PHP制作的掷色子点数抽奖游戏实例

    PHP制作的掷色子点数抽奖游戏实例,通过掷色子点数来达到抽奖的效果,为抽奖活动增添一些趣味性. 我们将在html页面中写下如下的html结构代码,.wrap用来放置色子和提示信息,#prize则是用来 ...

  7. Java后端高频面试题汇总

    Java后端面试题汇总 近来,分专题更新了Java后端面试题,此文章对这些文章做一个目录式的整理,方便查看 1.Java基础   https://www.cnblogs.com/autism-dong ...

  8. SSH框架之Hibernate第二篇

    1.1 持久化类的编写规则 1.1.1 什么是持久化类? 持久化类 : 与表建立了映射关系的实体类,就可以称之为持久化类. 持久化类 = Java类 + 映射文件. 1.1.2 持久化类的编写规则 ( ...

  9. for循环使用element的折叠面板遇到的问题-2

    需求:每次添加一个折叠面板时,让最新的折叠面板展开,其余的关闭 动态控制展开折叠面板,首先绑定name,v-model = activeName 我们的项目中是当添加折叠面板时,直接push进这个数组 ...

  10. CSS学习笔记-背景属性

    一.背景尺寸属性:    1.含义:        背景尺寸属性是CSS3中新增的一个属性,专门用于设置背景图片大小 2.格式:        1.1具体像素:             backgro ...