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

//只有登录的用户可以访问
1.统一返回格式

namespace webapi;

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

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

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

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

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

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

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

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

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

    /// 
    /// 获取结果
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    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 };
    }

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

2.自定义授权过滤器

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
usinsg Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;

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

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

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

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

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

        /// 
        /// 授权时执行此方法
        /// 
        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要输入服务

builder.Services.AddScoped<CustomAuthorizeAttribute>();

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

 builder.Services.AddControllers(opt =>
    {
        opt.Filters.Add<CustomAuthorizeAttribute>();
    })

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

  [AllowAnonymous]

        [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();
        }

你可能感兴趣的:(asp.net,core,自定义授权)