asp.net core自定义授权过滤器

//只有登录的用户可以访问

1.统一返回格式

csharp 复制代码
namespace webapi;

/// <summary>
/// 统一数据响应格式
/// </summary>
public class Results<T>
{
    /// <summary>
    /// 自定义的响应码,可以和http响应码一致,也可以不一致
    /// </summary>
    public int Code { get; set; }

    /// <summary>
    /// 中文消息提示
    /// </summary>
    public string? Msg { get; set; }

    /// <summary>
    /// 是否成功
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// 响应的数据
    /// </summary>
    public T? Data { get; set; }

    /// <summary>
    /// 返回的Token: 如果有值,则前端需要此这个值替旧的token值
    /// </summary>
    public string? Token { get; set; }

    /// <summary>
    /// 设置数据的结果
    /// </summary>
    /// <param name="data">数据</param>
    /// <returns></returns>
    public static Results<T> DataResult(T data)
    {
        return new Results<T> { Code = 1, Data = data, Msg = "请求成功", Success = true };
    }

    /// <summary>
    /// 响应成功的结果
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static Results<T> SuccessResult(string msg = "操作成功")
    {
        return new Results<T> { Code = 1, Data = default, Msg = msg, Success = true };
    }

    /// <summary>
    /// 响应失败的结果
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static Results<T> FailResult(string msg = "请求失败")
    {
        return new Results<T> { Code = -1, Data = default, Msg = msg, Success = false };
    }

    /// <summary>
    /// 参数有误
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static Results<T> InValidParameter(string msg = "参数有误")
    {
        return new Results<T> { Code = -1, Data = default, Msg = msg, Success = false };
    }

    /// <summary>
    /// 获取结果
    /// </summary>
    /// <param name="code"></param>
    /// <param name="msg"></param>
    /// <param name="data"></param>
    /// <param name="success"></param>
    /// <returns></returns>
    public static Results<T> GetResult(int code = 0, string? msg = null, T? data = default, bool success = true)
    {
        return new Results<T> { Code = code, Data = data, Msg = msg, Success = success };
    }

    /// <summary>
    /// 设置token结果
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public static Results<T> TokenResult(string token)
    {
        return new Results<T> { Code = 1, Data = default, Msg = "请求成功", Success = true, Token = token };
    }
}

2.自定义授权过滤器

csharp 复制代码
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
usinsg Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;

namespace webapi
{
    /// <summary>
    /// 授权过滤器
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter, IAuthorizeData
    {
        public CustomAuthorizeAttribute()
        {
        }

        /// <summary>
        /// 策略名称
        /// </summary>
        public string? Policy { get; set; }

        /// <summary>
        /// 可支持角色
        /// </summary>
        public string? Roles { get; set; }

        /// <summary>
        /// 以逗号分隔的方案列表,从中构造用户信息
        /// </summary>
        public string? AuthenticationSchemes { get; set; }

        //public CustomAuthorizeAttribute(string policy) => this.Policy = policy;

        /// <summary>
        /// 授权时执行此方法
        /// </summary>
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            // 需要排除具有AllowAnymons 这个标签的控制器
            // 过滤掉带有AllowAnonymousFilter
            if (HasAllowAnonymous(context))
            {
                return;
            }

            // 如果用户没有登录,则给出一个友好的提示(而不是返回401给前端)
            if (!context.HttpContext.User.Identity.IsAuthenticated) // 判断是否登录
            {
                context.Result = new JsonResult(Results<string>.FailResult("Token无效"));
            }
        }

        // 判断是否含有IAllowAnonymous
        private bool HasAllowAnonymous(AuthorizationFilterContext context)
        {
            if (context.Filters.Any(filter => filter is IAllowAnonymousFilter))
            {
                return true;
            }
            // 终节点:里面包含了路由方法的所有元素信息(特性等信息)
            var endpoint = context.HttpContext.GetEndpoint();
            return endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null;
        }
    }
}

在需要授权的方法上使用TypeFilter特性表示要使用授权过滤器,也可以是用 [ServiceFilter(typeof(CustomAuthorizeAttribute))]

serviceFilter要输入服务

csharp 复制代码
builder.Services.AddScoped<CustomAuthorizeAttribute>();

TypeFilter和serviceFilter都是局部注入,控制范围只能在某个控制器和方法,如果想要全局注入就要注入到控制器里

csharp 复制代码
 builder.Services.AddControllers(opt =>
    {
        opt.Filters.Add<CustomAuthorizeAttribute>();
    });

不需要授权的接口可以使用

csharp 复制代码
  [AllowAnonymous]
csharp 复制代码
        [TypeFilter(typeof(CustomAuthorizeAttribute))]
        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                // Date = Convert.ToDateTime("2023-12-10 "),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
相关推荐
绿荫阿广21 天前
使用.NET开发并上线一个小智AI对话机器人的MCP服务转接平台
.net·asp.net core·mcp
dephixf1 个月前
工业级部署指南:在西门子IOT2050(Debian 12)上搭建.NET 9.0环境与应用部署(进阶篇)
asp.net core·iot·设备管理系统·.net 9·能源管理监控系统
绿荫阿广2 个月前
.NET开发上手Microsoft Agent Framework(一)从开发一个AI美女聊天群组开始
.net·asp.net core·agent framework
wangbin55422 个月前
使用Scalar.AspNetCore来管理你的OpenApi
asp.net core
ArabySide2 个月前
【ASP.NET Core】分布式场景下ASP.NET Core中JWT应用教程
分布式·后端·asp.net core
绿荫阿广2 个月前
用纯.NET开发并制作一个智能桌面机器人(六):使用.NET开发一个跨平台功能完善的小智AI客户端
c#·.net·asp.net core·maui·winui
冷冷的菜哥3 个月前
ASP.NET Core文件分片上传
c#·asp.net·asp.net core·文件分片上传
冷冷的菜哥3 个月前
ASP.NET Core上传文件到minio
后端·asp.net·上传·asp.net core·minio
ArabySide3 个月前
【ASP.NET Core】双Token机制在ASP.NET Core中的实现
后端·asp.net core
ArabySide5 个月前
【ASP.NET Core】探讨注入EF Core的DbContext在HTTP请求中的生命周期
后端·http·asp.net·asp.net core·efcore