.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删除

 

posted on 2024-03-28 14:44  是水饺不是水饺  阅读(38)  评论(0)    收藏  举报

导航