Asp.net Core 基于Cookie的身份认证

Asp.net Core 有一套完整、丰富的身份验证流程,如果可以,就用,不要自己再造轮子,你造的过微软吗
—— 我说的

先上登录代码

Program.cs

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.cs

using Microsoft.AspNetCore.Authentication.Cookies;
using Uap.Areas.Admin.Service;

namespace Uap;

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration;

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // 将当前应用程序上下文放入MVC服务容器
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddScoped<IAdminService, AdminServiceImpl>();

        // 添加cookie身份认证
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.LoginPath = "/admin/login";
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
                options.AccessDeniedPath = "/navigator/forbidden";
            });
        // 配置 Cookie 策略
        services.Configure<CookiePolicyOptions>(options =>
        {
            // 默认用户同意非必要的 Cookie
            options.CheckConsentNeeded = context => true;
            // 定义 SameSite 策略,Cookies允许与顶级导航一起发送
            options.MinimumSameSitePolicy = SameSiteMode.Lax;
        });

        services.AddHttpContextAccessor();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseStaticFiles();

        app.UseHttpsRedirection();

        app.UseRouting();

        // 添加认证授权,需要在 UseAuthorization 之前
        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            //endpoints.MapControllers();
            endpoints.MapControllerRoute(
            name: "areas",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
          );
        });
    }
}

Controller
可以自己实现 XxxController 如 AdminController

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Uap.Areas.Admin.Models;
using Uap.Areas.Admin.Service;
        /// <summary>
        /// 登录方法
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("dologin")]
        [AllowAnonymous]
        //[ValidateAntiForgeryToken]
        public async Task<IActionResult> doLogin([FromBody] AdminModel admin)
        {
            // 1. 校验账号,获取用户信息
            if (!ModelState.IsValid) { }
			// 自己实现的对账号密码进行校验的方法,非Framework方法,成功返回 true,否则返回 false
            var valid = this.AdminService.SignIn(admin);
            if (!valid)
            {
                return Unauthorized();
            }

            // 2. 创建用户声明信息
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, admin.Username),
                new Claim(ClaimTypes.Role, "Administrator"),
            };

            // 3. 创建声明身份证
            var claimIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);

            // 4. 创建证件持有者
            var principal = new ClaimsPrincipal(claimIdentity);

            // 5. 登录
			// HttpContext 下 SignInAsync 方法默认你找不到
			// 需要引入 using Microsoft.AspNetCore.Authentication;
            await HttpContext.SignInAsync(principal);

            return Ok();
        }

[Authorize]注解
在控制器、方法添加该注解,就可以达到不登录就不能访问的目的

[AllowAnonymous]
在方法上添加该注解,允许匿名,至少登录页、登录接口你得让匿名访问

最终效果:

  • 登录成功,向前台返回 OK,前台处理,也可以在后台直接 Redirect(url) 重定向到目标地址
  • 在登录成功前,如果访问 [Authorize] 控制范围内的接口,将自动跳转到 options.LoginPath 所指定的页面,地址栏自动带有登录成功后需要跳转的来源地址,无需自己实现
    image
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章