aspnetcore最最简单的接口权限认证

五月一眨眼就过去,就当凑个数吧。

场景:

一个小小的项目,需要一个后台,就展示几个列表,连用户表、角色表等都不需要设计。

之前有写过identityserver4和jwt4的demo

(exercisebook/IdentityServer4&Serilog at main · liuzhixin405/exercisebook · GitHub

exercisebook/授权/授权一/JwtToken at main · liuzhixin405/exercisebook · GitHub),

但是这样一个项目中上这些肯定是大材小用。

微软提供的还有一个就是cookie,既然够简单,那么什么也不用设计,尽量做到最简单,而且后期还可以通过表设计来完善这个的后台登录模块。

首先我们要实现的就是接口代码的授权:

  [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [Authorize(Roles = "Admin")] // 要求"Admin"角色的授权
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

上面的特性使得WeatherForecastController接口需要权限才能访问,而GetWeatherForecast接口需要Admin角色就可以访问。

下面就通过program来配置及安全中心和授权策略:

using Microsoft.AspNetCore.Authentication.Cookies;

namespace auth_cookie
{
    /// <summary>
    /// 一个简单的Cookie身份验证和授权示例
    /// </summary>
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // 配置Cookie身份验证
            builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.Cookie.Name = "YourAuthCookie"; // 设置Cookie的名称
                    options.LoginPath = "/api/Auth/Login"; // 设置登录路径
                });

            // 配置授权服务
            builder.Services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
            });
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseHttpsRedirection();
            app.UseAuthentication(); // 启用身份验证
            app.UseAuthorization(); // 启用授权


            app.MapControllers();

            app.Run();
        }
    }
}

上面的代码够简单的吧,核心代码也就这几行。指定默认的scheme为cookie,写好注释。指定策略RequireAdminRole,要求角色Admin,都可以很灵活的多配置,通过数据库,配置文件等。

 // 配置Cookie身份验证
            builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.Cookie.Name = "YourAuthCookie"; // 设置Cookie的名称
                    options.LoginPath = "/api/Auth/Login"; // 设置登录路径
                });

            // 配置授权服务
            builder.Services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
            });

这样不算晚,还需要一个登录和登出的授权的接口,而且接口路径写好了,/api/Auth/Login

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace auth_cookie.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        //[HttpPost("login")]
        [HttpGet("login")] //方便测试
        public async Task<IActionResult> Login(string username, string password)
        {
            // 执行验证用户名和密码的逻辑
            //这里可以和存到数据库的用户和密码进行比对
            if(username != "admin" && password != "123456")
            {
                return BadRequest("Invalid username or password");
            }
            // 如果验证成功,创建身份验证Cookie
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, username),
                new Claim(ClaimTypes.Role, "Admin") // 添加用户角色
            };

            var claimsIdentity = new ClaimsIdentity(
                claims, CookieAuthenticationDefaults.AuthenticationScheme);

            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                new AuthenticationProperties());

            return Ok("Login successful");
        }

        //[HttpPost("logout")]
        [HttpGet("logout")]
        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return Ok("Logout successful");
        }
    }
}

上面的核心代码根据我们配置的做的设置,一一对应,要不然就无权访问WeatherForecastController了:

 var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, username),
                new Claim(ClaimTypes.Role, "Admin") // 添加用户角色
            };

            var claimsIdentity = new ClaimsIdentity(
                claims, CookieAuthenticationDefaults.AuthenticationScheme);

下面看看效果,访问 :https://localhost:7066/WeatherForecast,会自动跳转到https://localhost:7066/api/Auth/Login?ReturnUrl=%2FWeatherForecast

我们指定一下用户名和密码 https://localhost:7066/api/Auth/Login?username=admin&password=123456ReturnUrl=%2FWeatherForecast

再来访问 https://localhost:7066/WeatherForecast

退出登录,https://localhost:7066/api/auth/logout

再来访问 

https://localhost:7066/WeatherForecast

配合前端的后台管理,一个很简单的后台登陆就这样ok了。

源代码:

exercisebook/授权/授权三/auth_cookie at main · liuzhixin405/exercisebook · GitHub

posted @ 2023-05-31 10:21  星仔007  阅读(685)  评论(2编辑  收藏  举报