ASP.NET Core 3中的自定义授权

寻技术 ASP.NET编程 / 其他编程 2023年07月12日 98

您有一个Web API,并且想要实现自己的授权逻辑,该怎么做?您需要做四件事。

1. 创建您的自定义授权属性
2. 在控制器上使用自定义授权属性
3. 在自定义请求管道中间件中创建授权逻辑
4. 启动时注册中间件

 

创建您的自定义授权属性

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
 public class CustomAuthorizeAttribute : Attribute
 {
     public string[] AllowedUserRoles { get; private set; }
  
     public CustomAuthorizeAttribute(params string[] allowedUserRoles)
     {
         this.AllowedUserRoles = allowedUserRoles;
     }
 }

 

在控制器上使用自定义授权属性

 [ApiController]
 [Route("[controller]")]
 public class WeatherForecastController : ControllerBase
 {
  
     [HttpGet]
     [CustomAuthorize("Admin", "Supervisor", "Worker")]
     public string Get()
     {
         return "Sunny";
     }
 }

 

在自定义请求管道中间件中创建授权逻辑

 public static class CustomAuthorizationMiddleware
 {
     public static async Task Authorize(HttpContext httpContext, Func next)
     {
         var endpointMetaData = httpContext.GetEndpoint().Metadata;
  
         bool hasCustomAuthorizeAttribute = endpointMetaData.Any(x => x is CustomAuthorizeAttribute);
  
         if (!hasCustomAuthorizeAttribute)
         {
             await next.Invoke();
             return;
         }
  
         CustomAuthorizeAttribute customAuthorizeAttribute = endpointMetaData
                 .FirstOrDefault(x => x is CustomAuthorizeAttribute) as CustomAuthorizeAttribute;
  
         // TODO: change authorization logic
         bool isAuthorized = customAuthorizeAttribute.AllowedUserRoles
             .Any(allowedRole => httpContext.User.IsInRole(allowedRole));
  
         if (isAuthorized)
         {
             await next.Invoke();
             return;
         }
  
         httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
         await httpContext.Response.WriteAsync("unauthorized");
     }
 }

 

启动时注册中间件

 public class Startup
 {
     public Startup(IConfiguration configuration)
     {
         Configuration = configuration;
     }
  
     public IConfiguration Configuration { get; }
  
     // This method gets called by the runtime. Use this method to add services to the container.
     public void ConfigureServices(IServiceCollection services)
     {
         services.AddControllers();
     }
  
     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
         if (env.IsDevelopment())
         {
             app.UseDeveloperExceptionPage();
         }
  
         app.UseHttpsRedirection();
  
         app.UseRouting();
  
         app.Use(CustomAuthorizationMiddleware.Authorize);
  
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllers();
         });
     }
 }

确保在调用app.UseRouting()之后添加中间件。这样可以确保在将路由  信息添加到HttpContext 后执行您的中间件。

 

关闭

用微信“扫一扫”