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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章