将IOptions <>注入ApiKeyAuthorizeAttribute

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

我正在使用存储不同配置的选项模式,包括用于不同环境的API密钥。到目前为止,我一直在使用它并根据需要将我的值注入到类中。

但是,在尝试在控制器中设置授权并针对每个环境唯一的ApiKey运行验证时,我遇到了一些挑战,因为我无法将Iptions注入ApiKeyAuthorizeAttribute类来执行验证。

以下是我的控制器现在的样子:

[ApiKeyAuthorize]
public class NotificationSettingsController : Controller
{
    //some endpoints here
}

ApiKeyAuthorize类:

public class ApiKeyAuthorizeAttribute : Attribute, IAuthorizationFilter
{
    //////This...
    private readonly IOptions<MyConfig> _config;

    public ApiKeyAuthorizeAttribute(IOptions<MyConfig> config)
    {
        _config = config;
    }
    /////////...is what I am trying to accomplish
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var request = context.HttpContext.Request;

        var foundApiKeys = request.Headers.TryGetValue("ReplaceWithOptionsApiKeyName", out var requestApiKeys);

        if (!foundApiKeys || requestApiKeys[0] != "ReplaceWithOptionsApiKeyValue")
        {
            context.Result = new UnauthorizedResult();
        }
    }
}

我的问题是这里注入是不可能的,但我需要从IOptions <>获取一个值来运行ApiKey验证。

asp.net-core dependency-injection authorization asp.net-core-webapi
1个回答
1
投票

属性是就地构造的,因此不可能将依赖项注入其中。但是,ASP.NET Core提供了一种解决方法。您可以使用ServiceFilter属性代替直接应用该属性,并将其传递给您要应用的过滤器类型:

[ServiceFilter(typeof(ApiAuthorizeAttribute))]

这将动态地将过滤器应用于控制器/操作,同时使用它同时需要的任何依赖项对其进行实例化。但是,它确实限制了你的另一个方向。例如,如果您需要执行以下操作:

[ApiAuthorizeAttribute(Roles = "Admin")]

使用ServiceFilter属性无法实现此目的,因为您无法在此处传递属性值(如Roles)以及类型。

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