3

I'm currently developing the Authorization module on a framework of mine.

I have the following class so far:

public interface IAuthorizationManager<C>
       where C : AuthorizationConfiguration
{
    void Configure(C configuration);
}

One of my implementations is going to be OAuth authentication.

For that I have created the following manager:

public class OAuthAuthorizationManager : IAuthorizationManager<OAuthConfiguration>
{
    private IOAuthAuthorizationServerProvider _authorizationProvider;
    private IAuthenticationTokenProvider _refreshTokenProvider;

    public AuthorizationManager(IOAuthAuthorizationServerProvider authorizationProvider,
                                IAuthenticationTokenProvider refreshTokenProvider)
    {
        this._authorizationProvider = authorizationProvider;
        this._refreshTokenProvider = refreshTokenProvider;
    }

    public void Configure(OAuthConfiguration configuration)
    {
       configuration.Application.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions() {
             AllowInsecureHttp = !configuration.IsSecure,
             TokenEndpointPath = new PathString(configuration.TokenEndpoint),
             AccessTokenExpireTimeSpan = configuration.TokenExpiration,
             Provider = _authorizationProvider,
             RefreshTokenProvider = _refreshTokenProvider
       });
       configuration.Application.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

Now, here's the thing, the implementations of IOAuthAuthorizationServerProvider and IAuthenticationTokenProvider are going to be injected through the constructor.

I am using Ninject for dependency injection.

In my application's startup project I have the following module:

public class AuthorizationModule : ApplicationModule
{
      public override void Load()
      {
          Kernel.Bind<IOAuthAuthorizationServerProvider>().To<AuthorizationProvider<User, Client>>();
          Kernel.Bind<IAuthenticationTokenProvider>().To<RefreshTokenProvider<RefreshToken>();

          Kernel.Bind<IAuthorizationManager<OAuthConfiguration>>().To<OAuthAuthorizationManager>();
      }
}

The problem is that the interfaces IOAuthAuthorizationServerProvider and IAuthenticationTokenProvider are part of the Owin.Security.OAuth library, so when I am configuring the injection, my application's startup project needs to directly reference this library and its dependencies. This pollutes my packages.config. I don't like the idea to have the same library referenced twice in my solution, when only one project actually uses it.

AuthorizationProvider<User, Client> and RefreshTokenProvider<RefreshToken> are classes of mine, so there's no problem with those.

I was thinking of maybe creating an interface like this (of course i'd chose another name):

public class IMyOAuthAuthorizationServerProvider : IOAuthAuthorizationServerProvider { }

public class IMyAuthenticationTokenProvider : IAuthenticationTokenProvider { }

Along with the associated changes:

public AuthorizationManager(IMyOAuthAuthorizationServerProvider authorizationProvider, IMyAuthenticationTokenProvider refreshTokenProvider)
{
    this._authorizationProvider = authorizationProvider;
    this._refreshTokenProvider = refreshTokenProvider;
}

And:

Kernel.Bind<IMyOAuthAuthorizationServerProvider>().To<AuthorizationProvider<User, Client>>();
Kernel.Bind<IMyAuthenticationTokenProvider>().To<RefreshTokenProvider<RefreshToken>>();

Of course the Owin.Security.OAuth will keep being referenced, but this time indirectly, therefore I don't need to install them (via NuGet) on my main project.

I wanted to know if this is a common practice, what are the disadvantages of this approach, and any tips or alternative solution would be highly (and gladly) accepted.

  • Did you try that? You need to reference the assembly of the base-type to use a derived type. – Patrick Jul 2 '15 at 5:49
3

Does Ninject provide a configuration-file based approach (like here)? I think if you did that the type would be dynamically loaded, and voila! - no dependency in your project.

The drawback is that now you have potential runtime failures rather than compile-time ones, but I think that's what you would rather have in your situation.

  • This is very interesting. I would prefer a compile time safe solution, but nevertheless this is pretty much feasible and solves my problem just as asked – Matias Cicero Jul 2 '15 at 2:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.