属性和自定义属性-授权如何工作?

问题描述 投票:0回答:1

我正在尝试模拟[Authorize]属性,因为我发现您可以将属性放在整个类的顶部而感到惊讶,除非这样做,否则它会以某种方式阻止所有用户运行类中的方法。 。某事...

我查找了创建自定义属性的过程,发现了一些答案,这些回答基本上说,除非我们使用反射,否则属性不可能阻止方法的调用,因此我决定深入研究Authorize属性,但只能找到“接口“元数据文件上的方法基本上是这样

[Authorize]属性到底在做什么,我如何实现使用反射实际执行操作的属性?例如。当归于一个类时,以下内容不执行任何操作:

[System.AttributeUsage(System.AttributeTargets.Class)]
public class Authorise : System.Attribute
{
    public Authorise()
    {
        if (!SomeBoolCondition) throw new Exception ("Oh no!");
    }
}

我无法理解Authorize属性如何进行检查,然后将程序重定向到登录页面。

c# attributes custom-attributes
1个回答
0
投票
如果要使用自定义属性来实现自己的授权逻辑,则还需要在请求管道中创建并注册middleware。您的中间件将收到整个HttpContext,您可以使用它来通过其元数据检查端点的CustomAuthorizeAttribute。在这里,您可以实现授权逻辑,并决定通过“ await next.Invoke()”继续在管道中处理请求,或者停止处理并将未经授权的响应返回给客户端。

属性类:

[AttributeUsage(AttributeTargets.Class)] public class CustomAuthorizeAttribute : Attribute { public IEnumerable<string> AllowedUserRoles { get; private set; } public CustomAuthorizeAttribute(params string[] allowedUserRoles) { this.AllowedUserRoles = allowedUserRoles.AsEnumerable(); } }

具有自定义属性的控制器:

[ApiController] [Route("[controller]")] [CustomAuthorize("Admin", "Supervisor", "Worker")] public class WeatherForecastController : ControllerBase { }

使用自定义中间件启动。配置:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.Use(async (httpContext, next) => { var endpointMetaData = httpContext.GetEndpoint() .Metadata; bool hasCustomAuthorizeAttribute = endpointMetaData.Any(x => x is CustomAuthorizeAttribute); if (hasCustomAuthorizeAttribute) { // get the endpoint's instance of CustomAuthorizeAttribute CustomAuthorizeAttribute customAuthorieAttribute = endpointMetaData .FirstOrDefault(x => x is CustomAuthorizeAttribute) as CustomAuthorizeAttribute; // here you will have access to customAuthorizeAttribute.AllowedUserRoles // and can execute your custom logic with it bool isAuthorized = true; if (isAuthorized) { // continue processing the request await next.Invoke(); } else { // stop processing request and return unauthorized response httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; await httpContext.Response.WriteAsync("Unauthorized"); } } }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }

© www.soinside.com 2019 - 2024. All rights reserved.