How can I access AppSettings from an ActionFilterA

2019-04-09 23:02发布

I am currently trying to develop a WebAPI (.NET Core) which has some controller actions that should use HTTP Basic Authentication. To implement this, I have written an ActionFilterAttribute which I can then use in my controller to restrict access to certain actions. This all workes well if I do something like this:

BasicAuthAttribute.cs

public class BasicAuthAttribute : ActionFilterAttribute{
    private string _username { get; set; }
    private string _password { get; set; }

    public BasicAuthAttribute(string username, string password) {
        _username = username;
        _password = password;
    }

    public override void OnActionExecuting(ActionExecutingContext actionContext) {
    //do Auth check...
    }
}

In the controller I then use it as following:

SomeController.cs

[BasicAuth("testuser","testpassword")]
[HttpGet("{id}")]
public IActionResult Get(string id) {
    return new ObjectResult("Test");
}

Now I do not want to specify username ond password in SomeController.cs. Instead I would like to store them in appsettings.json. How is it possible to access values stored in appsettings.json in the OnActionExecuting method in the ActionFilterAttribute?

If I change the constructor of BasicAuthAttribute to the following, .Net expects me to pass the settings, which is not possible. Dependency Injection seems not to work here.

public BasicAuthAttribute(IOptions<AppSettings> appSettings) {}

Any help or ideas would be appreciated

UPDATE based on Set's answer:

I ended up changing the attribute to a filter. In case anybody else needs it see the working solution below:

BasicAuthFilter.cs

public class BasicAuthFilter : IActionFilter{

protected AppSettings _settings { get; set; }

public BasicAuthAttribute(IOptions<AppSettings> appSettings) {
    _settings = appSettings;
}

public void OnActionExecuted(ActionExecutedContext context) {
    //nothing to do here
}

public override void OnActionExecuting(ActionExecutingContext actionContext) {
    //do Auth check...
}

}

SomeController.cs

public class SomeController : Controller {
   [TypeFilter(typeof(BasicAuthFilter))]
   [HttpGet("{id}")]
   public IActionResult Get(string id) {
        return new ObjectResult("Test");
   }
}   

1条回答
姐就是有狂的资本
2楼-- · 2019-04-09 23:54

Filters section in ASP.NET Core documentation explains how to use DI:

If your filters have dependencies that you need to access from DI, there are several supported approaches. You can apply your filter to a class or action method using one of the following:

  • ServiceFilterAttribute
  • TypeFilterAttribute
  • IFilterFactory implemented on your attribute
查看更多
登录 后发表回答