.net core cookie 身份认证 (二)
.net core cookie 身份认证
cookie 认证 包含
returnUrl 跳转路径
LoginPath 登录路径
LogoutPath 注销路径
AccessDeniedPath 访问拒绝路径
默认 文件夹 /Account/Login 等等
注意 :
一定要声明身份验证类型
CookieAuthenticationDefaults.AuthenticationScheme
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await _contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), properties);
参考 详解ASP.NET Core 之 Identity 入门(一) - 知乎 (zhihu.com)
登录 其实 有三种方式
第一种 是调用 ControllerBase.SignIn 最后需要调用 signInResult.ExecuteResultAsync
第二种 调用 ControllerBase.HttpContext 这种方式在异步多线程 不安全
第三种 调用 _contextAccessor.HttpContext.SignInAsync 这种方式通过注入 IHttpContextAccessor 这种多线程场景下安全
Microsoft.AspNetCore.Mvc.SignInResult signInResult =
base.SignIn(new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
},
CookieAuthenticationDefaults.AuthenticationScheme);
//执行
await signInResult.ExecuteResultAsync(base.ControllerContext);
//contextAccessor线程安全
await _contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties
{
IsPersistent = true
});
//HttpContext 线程不安全
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties
{
IsPersistent = true
});
简单的配置
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
中间件身份验证启用
app.UseAuthentication();
现在进行一些配置
比如 cookie 绝对过期时间 cookie名称 不使用 默认 登录路径 options.RequireAuthenticatedSignIn 默认为true
必须经过 身份验证才能登录
在ASP。NET Core,RequireAuthenticatedSignIn属性用于确定是否必须对用户进行身份验证,以便身份验证中间件在成功身份验证后创建ClaimsPrincipal。当此属性设置为true时,中间件将仅为经过身份验证的请求创建ClaimsPrincipal。如果请求未通过身份验证,则不会创建ClaimsPrincipal。
以下是如何在ASP中配置RequireAuthenticatedSignIn。NET核心:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
// Configure JWT authentication parameters
});
services.Configure<CookieAuthenticationOptions>(options =>
{
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
options.AccessDeniedPath = "/Account/AccessDenied";
// Set RequireAuthenticatedSignIn to true
options.RequireAuthenticatedSignIn = true;
});
services.AddControllersWithViews();
}
在本例中,对于cookie身份验证,RequireAuthenticatedSignIn设置为true(CookieAuthenticationOptions)。这意味着,当用户通过cookie成功进行身份验证时,将创建ClaimsPrincipal。如果用户未通过身份验证,则不会创建ClaimsPrincipal,并且该请求将不会被视为已通过身份验证。
请记住,根据应用程序的要求,将RequireAuthenticatedSignIn设置为true可能会产生影响。在决定是否使用此选项之前,必须了解身份验证流和您想要实现的行为。
builder.Services.AddAuthentication(
options =>
{
//添加 默认身份认证 处理方案
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// options.RequireAuthenticatedSignIn = false;
}
).AddCookie(options =>
{
//options.EventsType = typeof(CustomCookieAuthenticationEvents);
//cookie名称
options.Cookie.Name = "myCookie";
//匿名跳转路径
options.AccessDeniedPath = "/Forbid/";
//定义登录路径
options.LoginPath = "/Login";
//定义注销路径
options.LogoutPath = "/Login/LoginOut";
//过期时间
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
//滑动过期
options.SlidingExpiration = true;
});
后台 控制器逻辑
//记住我 配置
AuthenticationProperties properties = new AuthenticationProperties{IsPersistent = input.RememberMe};
利用 HttpContext.SignInAsync 将 claim 数据存入到 cookie中 这里 不要忘记 CookieAuthenticationDefaults.AuthenticationScheme 提供 身份认证方案名称
利用 HttpContext.SignOutAsync 登出 将cookie 删除
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using TestCookieAuth.Models;
namespace TestCookieAuth.Controllers
{
public class LoginController : Controller
{
private readonly ILogger<LoginController> _logger;
private readonly IHttpContextAccessor _contextAccessor;
public LoginController(ILogger<LoginController> logger, IHttpContextAccessor contextAccessor)
{
_logger = logger;
_contextAccessor = contextAccessor;
}
public IActionResult Index(string returnUrl = null)
{
if (!string.IsNullOrEmpty(returnUrl))
{
ViewData["ReturnUrl"] = returnUrl;
}
return View();
}
[HttpPost("Login")]
public async Task<IActionResult> LoginAsync(LoginInputDto input)
{
if (!ModelState.IsValid)
{
return RedirectToPage("Error");
}
if (input.Email.Equals("1"))
{
List<Claim> claims = new List<Claim>()
{
new Claim(ClaimTypes.Email, input.Email)
};
AuthenticationProperties properties = new AuthenticationProperties
{
//记住我
IsPersistent = input.RememberMe,
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await _contextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), properties);
if (!string.IsNullOrEmpty(input.ReturnUrl))
{
return Redirect(input.ReturnUrl);
}
return RedirectToAction("Index", "Home");
}
return View();
}
[HttpGet("LoginOut")]
public async Task<IActionResult> LoginOutAsync()
{
await _contextAccessor.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Index", "Home");
}
}
}
LoginInputDto 类定义
using System.ComponentModel.DataAnnotations;
namespace TestCookieAuth.Models
{
/// <summary>
/// login登陆 输入
/// </summary>
public class LoginInputDto
{
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
/// <summary>
/// 记住我
/// </summary>
public bool RememberMe { get; set; }
/// <summary>
/// 跳转路径
/// </summary>
public string? ReturnUrl { get; set; }
}
}
测试

登录 之后 cookie成功写入

登出 cookie删除

浙公网安备 33010602011771号