mhtsbt
mhtsbt

Reputation: 1079

Simple injector webapi authorization attribute

I'm trying to create a custom authorization-attribute for my WebApi project.

In this attribute I would like to inject an IAuthModule object. I have no clue how I could implement this. I've found some solutions on the web but I have not been successful with any of them.

This is what I have so far:

public void Configuration(IAppBuilder app)
{
    // WebApi config
    HttpConfiguration config = new HttpConfiguration();

    // SimpleInjector
    var container = new SimpleInjector.Container();

    container.Register<IAuthModule, CoreAuthModule>();

    container.RegisterWebApiFilterProvider(config);
    container.RegisterWebApiControllers(config);

    container.Verify();

    config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

    // Setup Oauth
    ConfigureOAuth(app, container.GetInstance<IAuthModule>());

    WebApiConfig.Register(config);

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);
}

and the attribute:

public class CustomAuthorizationAttribute : AuthorizeAttribute
{
    // how can I inject something here?
    public IAuthModule AuthModule { get; set; }

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        return false;
    }
}

Upvotes: 2

Views: 2483

Answers (1)

Steven
Steven

Reputation: 172606

The Simple Injector Web API integration guide goes into more details about this in the Injecting dependencies into Web API filter attributes section. What it basically describes is that you need to do two things:

  1. Use the RegisterWebApiFilterProvider extension method to allow Simple Injector to build-up Web API attributes.
  2. Register a custom IPropertySelectionBehavior to make sure Simple Injector will inject dependencies into your attribute's properties.

So this basically comes down to adding the following registration:

var container = new Container();

container.Options.PropertySelectionBehavior = new ImportPropertySelectionBehavior();

container.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

Where the ImportPropertySelectionBehavior is implemented as follows:

using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection;
using SimpleInjector.Advanced;

class ImportPropertySelectionBehavior : IPropertySelectionBehavior {
    public bool SelectProperty(Type type, PropertyInfo prop) {
        return prop.GetCustomAttributes(typeof(ImportAttribute)).Any();
    }
}

This custom IPropertySelectionBehavior enables explicit property injection where properties are marked with the System.ComponentModel.Composition.ImportAttribute attribute. Any property that is marked with this attribute will get injected.

Do note that dependency injection in attributes is sub optimal as described here and here.

Upvotes: 8

Related Questions