一个系统,用户身份认证少不了, Core提供完整的解决方案Identity,用户创建和维护登录名;也提供能cookie和JwtBearer认证方案,当然你可以使用第三方认证Oauth、openId。项目没有采用前后端分离,是一个标准的mvc项目,所以本文采用系统提供的cookie认证 记录一下简单认证流程,(1)使用用户账号密码进行登录,验证合法登录(2)确认合法身份之后,会颁发一个认证票据(加密)会携带与该用户相关的身份、权限以及其他信息。(3)退出。
主要会使用Microsoft.AspNetCore.Authentication.Abstractions包中 AuthenticationHttpContextExtensions类,它是基于HttpContext上公开身认证的扩展法:
登录创建一个cookie认证
这里涉及几个对象:Claim声明常常代表,认证用户身份的元数据信息,比如手机号、邮箱、用户名等等。ClaimsIdentity声明主体,代表一个认证用户的身份证,当然包含声明的集合。ClaimsPrincipal身份证持有者。
流程:创建一个包含用户信息的 cookie需要构造一个ClaimsPrincipal。将序列化用户信息并将其存储在中 cookie 。
用必要的 Claim来构造一个ClaimsIdentity,然后调用 SignInAsync 来登录用户。
public async Task<Result> UserLogin([FromForm] UserLoginInput input){//登录逻辑var model = userService.UserLogin(input);//1.创建cookie 保存用户信息,使用claim。将序列化用户信息并将其存储在cookie中var claims = new List<Claim>(){new Claim(ClaimTypes.MobilePhone,model.Mobile),new Claim(ClaimTypes.Name,model.UserName),new Claim("Id",model.SysNo.ToString())};//2.创建声明主题 指定认证方式 这里使用cookievar claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);//3.配置认证属性 比如过期时间,是否持久化。。。。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,//持久化 ,比如 登录的时候 勾选记住我 复选框//IssuedUtc = <DateTimeOffset>,//绝对cookie过期//RedirectUri = <string>// The full path or absolute URI to be used as an http// redirect response value.};//4.登录await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);return Result.ResponseSuccess();}
SignInAsync 创建一个加密的 cookie ,并将其添加到当前响应中。
退出
退出很简单,主要用户清除cookie
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
获取认证信息
登录之后,我们通常会获取一些声明中的信息,可以使用 HttpContext.User 将会返回一个ClaimsPrincipal对象
ClaimsPrincipal principal = HttpContext.User;if (null != principal){foreach (Claim claim in principal.Claims){var ii = "CLAIM TYPE: " + claim.Type + "; CLAIM VALUE: " + claim.Value + "</br>";}}
统一处理获取到的信息,赋值UserViewModel实例CurrentLoginUser
public class BaseController : Controller{public UserViewModel CurrentLoginUser{get{var principal = HttpContext.User;if (principal != null){return new UserViewModel(){UserName = principal.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value,Mobile = principal.Claims.FirstOrDefault(x => x.Type == ClaimTypes.MobilePhone)?.Value,SysNo = new Guid(principal.Claims.FirstOrDefault(x => x.Type == "Id")?.Value ?? Guid.Empty.ToString())};}return null;}}
使用
var userId = CurrentLoginUser.SysNo;
startup类配置
在ConfigureServices方法添加
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>{options.LoginPath =new PathString("/User/Login");});
在Configure方法添加
application.UseAuthentication();application.UseAuthorization();
参考:
/zh-cn/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1