Moving towards a provider model

93 views
Skip to first unread message

Werner Strydom

unread,
Jun 19, 2012, 4:17:04 PM6/19/12
to dotnet...@googlegroups.com
Hello,

Every time I create an OpenID provider or OAuth 2.0 Authorization Server, I find myself spending a lot of time implementing code get the implementations working.  It is time consuming and error prone.  I wondering whether there is a possibility to move towards a provider model, similar to the membership, role and profile providers that come with .NET. This will allow us to implement a providers for clients, nonces, crypto keys and resource owners. The same applies to OpenID.  

I think such providers will enable more robust implementations.  If there is enough interest, I'll post proposed classes here for further discussion.

Thanks,
Werner

Werner Strydom

unread,
Jun 19, 2012, 5:51:22 PM6/19/12
to dotnet...@googlegroups.com
In OAuth 2.0 determining whether an application is authorized, authorizing application and revoking access is pretty important.  So I suggest that we have define a provider for it similar to the following:

    
    public interface IAuthorizationProvider 
    {
        void Authorize(string username, string clientIdentifier, DateTime issuedOn, HashSet<string> scope);
        bool IsAuthorized(string username, string clientIdentifier, DateTime issuedOn, HashSet<string> scope);
        void RevokeAuthorization(string username, string clientIdentifier);
    }
    
    public interface IAuthorizationProviderFactory 
    {
        IAuthorizationProvider Create();
    }

    public class DefaultAuthorizationProviderFactory : IAuthorizationProviderFactory
    {
        public IAuthorizationProvider Create() 
        {
            // read the configuration and create the appropiate MySqlAuthorizationProvider
        }
    }

    // in a MySQL dll
    public class MySqlAuthorizationProvider : IAuthorizationProvider 
    {
        // code to use MySQL for authorizations
    }

    // in a Sql dll
    public class SqlAuthorizationProvider : IAuthorizationProvider 
    {
         // code to use SQL Server for authorizations
    }


The default authorization provider factory can read the type from the configuration and create the provider from there.  However, I can implement my own using my own ORM.  The question is how to create the factory when it has other dependencies, such as IDbContext (in Entity Framework).

A common technique is to use a service container of one's choice to create the factory.  This may necessitate another interface to encapsulate a service container with a default implementation that hard codes the default dependencies. 

    
    public interface IServiceProvider
    {
        object GetService(Type serviceType);
    }

    public class DefaultServiceProvider
    {
        public object GetService(Type serviceType)
        {
            if(serviceType == typeof(IAuthorizationProviderFactory)) {
                return new DefaultAuthorizationProviderFactory();
            }
            return null;
        }
    }

    // in a unity dll
    public class UnityServiceProvider : IServiceProvider
    {
        public object GetService(Type serviceType) {
            // use unity to resolve service type
        }
    }


I can then implement a service provider using Unity, Castle or any other container of my choosing.  There may be two ways to register my own service provider, namely configuration or in code.  I prefer the latter since it allows reuse amongst different projects. However, doing it in configuration may be preferable for some.

Any feedback is welcome.

Werner




Andrew Arnott

unread,
Jun 20, 2012, 10:46:59 AM6/20/12
to dotnet...@googlegroups.com
Hi Werner,

Thanks for sharing.  Some of this, like the Authorize method, lies outside the scope of interest to the core DNOA library, but all of this seems very relevant to including in the DotNetOpenAuth.ApplicationBlock.  Is that where you were proposing centralizing this code?  

BTW, I particularly like your use of interfaces and abstracting the db layer for various providers.  Although the IAuthorizationProviderFactory seemed just a tad on the side of over-doing it.  Presumably if someone is using IoC to inject providers into their code, which seems to be the role of this ProviderFactory, they'd have more than just one method on it so they could create providers for different services, and having one interface dedicated to nothing but creating another interface instance makes me wonder "why do you give me a factory that does nothing but create something else?  Why not just give me the something else?"
--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/j-82_XgYLsYJ.
To post to this group, send email to dotnet...@googlegroups.com.
To unsubscribe from this group, send email to dotnetopenid...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/dotnetopenid?hl=en.


--
--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre

Werner Strydom

unread,
Jun 20, 2012, 1:49:13 PM6/20/12
to dotnet...@googlegroups.com
I haven't really given it any thought where to put this.

As for the factory method, my experience tells me there are two types of audiences:
  1. those that don't use IoC containers and tend to hardcode the creation of their custom providers
  2. those that don't use IoC containers and tend to use configuration for their containers
  3. those that use IoC containers to create and manage the lifetime of objects
In the first two cases, the (DNOA) library would be unable to create the provider without some factory.  The provider factory serves to encapsulate the process of creating the container.  By default it would read the configuration for the provider type and create it.

In option 3, the factory seems redundant. If one omits the need for IServiceProvider then someone can implement a custom factory that uses an IoC container to create the provider.  However, when there are several providers, then one runs into the problem of implementing as many factories to use the IoC container. Hence the need for an IServiceProvider.

The default factory can always try to resolve the provider first before attempting to create it.  So if we are using an IoC container we simply register the provider in the container and we are done. There is then no need for those who implement custom providers to implement corresponding factories.

At least that is the logic I was following.  Any thoughts?

Andrew Arnott

unread,
Jun 21, 2012, 11:40:19 AM6/21/12
to dotnet...@googlegroups.com
OK, I think I'm beginning to understand what you're going for better, in which case I suppose the extra provider factory interface may make sense.  At least in some cases.

I don't think DNOA needs access to the IAuthorizationProvider interface.  For example, its Authorize method isn't one that DNOA will ever call (that's up to the hosting site to call when the user approves the authorization).  The other two are interesting from DNOA's perspective, and there is already an interface defined to capture that behavior.  

Eventually, perhaps when DNOA takes a hard dependency on .NET 4.0, we may use MEF, at least internally, to discover services.  It wouldn't be strictly required that the host application use MEF, but if it did then DNOA might fit well into that model.  I'd be interested in hearing your thoughts on this too.

Until that time, DNOA currently has properties/constructors that take interfaces that DNOA will need to perform its work, including the interfaces that provide IAuthorizationProvider-like behavior, but without the Authorize method.  If we put the interfaces you're proposing, and some common implementations of those interfaces, into the ApplicationBlock, then I think the web apps can benefit for the reasons you've given, and use those classes to also supply the interfaces that DNOA does know about. 

What do you think?

--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre


--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/nNmtJwDItg0J.

Werner Strydom

unread,
Jun 21, 2012, 5:21:33 PM6/21/12
to dotnet...@googlegroups.com
Don't look at the providers just from a framework perspective only. The aim of the providers is to provide a consistent interface to share implementations to manage clients, crypto keys, authorizations and other data critical for OAuth 2.0 implementations. For that I believe the Authorize method to be important, even though DNOA doesn't call it directly, because it allows the provider to encapsulate the management of authorizations in a consistent and robust manner.  I'd like to write that code once and only once.

Please don't introduce a dependency on MEF. A couple of months ago I tried using MEF in my web applications and its pretty messy, intrusive, and problematic.  I then tried to use MEF for some things, like extension points, and an IoC container for others but that left me with a larger mess. So I reverted back to IoC and it works fine.  I would instead suggest you provide the necessary extension points for developers to use MEF or an IoC container of their choice to integrate and extend DNOA.

DNOA is a framework, not an application. As a framework, it should refrain from introducing dependencies that would make it harder for  developers to use the framework.

It seems like the IAuthorizationServerHost grew organically over time.  Its because of this interface,  that I started looking at using providers. It is god-like in nature, thus cumbersome to implement and difficult to reuse between applications.  Breaking it into several smaller interfaces, each with implementations that promote reuse, will ease implementing an AuthorizationServer.

BTW. Do you use ReSharper?

Werner


Andrew Arnott

unread,
Jun 25, 2012, 1:21:53 AM6/25/12
to dotnet...@googlegroups.com
Point well taken regarding the IAuthorizationServerHost interface.  I'm interested in studying your proposal further.

Regarding MEF, I think the strongest dependency on it that DNOA would ever take is simply adding the MEF attributes to the appropriate types and members such that a MEF host would automatically just work.  It wouldn't prevent manual wire up or the use of a different IoC container, AFAIK.  Of course the attributes' presence themselves will cause issues for anyone performing reflection if .NET 4.0 isn't present, which is why I hold off for now.

As for ReSharper, I've tried using it a couple times.  At the moment, I don't use it mostly because I'm using Visual Studio 2012 and the ReSharper I had was installed only on VS 2010.  I'm not thrilled about the perf and memory hit that ReSharper incurs either, so I don't usually use it.

--
Andrew Arnott
"I [may] not agree with what you have to say, but I'll defend to the death your right to say it." - S. G. Tallentyre


--
You received this message because you are subscribed to the Google Groups "DotNetOpenAuth" group.
To view this discussion on the web visit https://groups.google.com/d/msg/dotnetopenid/-/ciZJHD6dEG0J.

Richard Collette

unread,
Jun 26, 2012, 12:26:45 PM6/26/12
to dotnet...@googlegroups.com
I've had similar issues with ReSharper.    I read an MSDN article recently about convention based MEF in .NET 4.5.   There was mention of eliminating the need for at least some of the attributes.   I didn't get a chance to get through the whole article in detail through.
To unsubscribe from this group, send email to dotnetopenid+unsubscribe@googlegroups.com.

Werner Strydom

unread,
Jun 26, 2012, 3:01:34 PM6/26/12
to dotnet...@googlegroups.com
I use ReSharper. If there was a dotSettings file for the solution that will suggest to me how you want the code to be formatted, dealing with headers etc.

As for MEF, I migrated my apps (MVC, PowerShell, WinForms, WCF) to NET 4.5 and tried to use the convention based registration.  After two weeks trying to get that to work across several assemblies and application, I started to use the attributes again.  In the end, my code looked like a mess.  I then ripped MEF out of the system all together.  As it stands it is not a good replacement for an IoC container like Unity or Castle.  I'll wait a couple of years before trying again.

When using an IoC alongside MEF, the challenge comes when one has the following dependencies 

MyController - AuthorizationServer - AuthorizationServerHost - MyDatabaseContext

MyDatabaseContext and MyController is managed by my IoC and AuthorizationServer may be using MEF to resolve AuthorizationServerHost and other providers. Seamlessly integrating MEF and IoC so that we have no "leaks" is no trivial matter.  

I'm not sure that adding the complexity to any application is warranted. 
Reply all
Reply to author
Forward
0 new messages