将IOptions <>注入ApiKeyAuthorizeAttribute

时间:2019-04-18 15:36:49

标签: asp.net-core dependency-injection authorization asp.net-core-webapi

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

但是,在尝试在控制器中设置授权并针对每个环境针对我的ApiKey运行验证时,我遇到了一些挑战,因为我无法将IOptions注入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验证。

1 个答案:

答案 0 :(得分:1)

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

[ServiceFilter(typeof(ApiAuthorizeAttribute))]

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

[ApiAuthorizeAttribute(Roles = "Admin")]

使用ServiceFilter属性是不可能实现的,因为您不能将属性值(例如Roles)与类型一起传递。