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();
        }
相关推荐
Esofar13 天前
Dddify:给 ASP.NET Core 项目一套轻量、清晰、可落地的 DDD 基础设施
c#·ddd·asp.net core·cqrs·dddify·clean architecture
CSharp精选营21 天前
.NET 8 Web开发入门(三):解构引擎——依赖注入(DI)与中间件管道
中间件·asp.net core·依赖注入·ioc容器·请求管道·服务生命周期
医疗信息化王工2 个月前
基于ASP.NET Core的医院输血审核系统设计与实现
后端·mvc·asp.net core·输血审核
医疗信息化王工2 个月前
基于ASP.NET Core的住院日志统计系统设计与实现
后端·layui·asp.net core·npoi·dapper
无风听海2 个月前
.NET10之HttpContext.RequestServices 深入解析
.net·asp.net core
硅基喵2 个月前
聊聊 ASP.NET Core 中间件和过滤器的区别
asp.net core
小邓的技术笔记2 个月前
Serilog:从结构化日志认知到 .NET 工程落地
asp.net core·结构化日志·可观测性·serilog
硅基喵2 个月前
Serilog:从结构化日志认知到 .NET 工程落地
asp.net core·可观测性
硅基喵2 个月前
ASP.NET Core 外部依赖调用治理实战:HttpClientFactory、Polly 与幂等边界
asp.net core·架构设计
硅基喵3 个月前
ASP.NET Core 认证鉴权实战:JWT、Policy 与权限边界怎么落地
asp.net core·工程实践