【问题标题】:Injecting IOptions<> into ApiKeyAuthorizeAttribute将 IOptions<> 注入 ApiKeyAuthorizeAttribute
【发布时间】:2019-09-08 23:49:07
【问题描述】:

我正在使用存储不同配置的选项模式,包括不同环境的 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 验证。

【问题讨论】:

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


    【解决方案1】:

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

    [ServiceFilter(typeof(ApiAuthorizeAttribute))]
    

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

    [ApiAuthorizeAttribute(Roles = "Admin")]
    

    使用ServiceFilter 属性无法实现此目的,因为您无法将属性值(如此处的Roles)与类型一起传递。

    【讨论】:

    • 小细节给那些将来会搜索这个问题的人:不要忘记在 Startup.cs 中添加services.AddScoped&lt;ApiKeyAuthorizeAttribute&gt;(),否则完美的解决方案!
    猜你喜欢
    • 2019-06-18
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    相关资源
    最近更新 更多