I am writing a WCF service using .NET 4.5 and SimpleInjector. It is a REST service (using http/get/post).
I need to add an authorisation layer to my service. After a lot of messing around, I now have a custom authorisation manager based on ServiceAuthorizationManager.
All the examples I've seen (and I have found many) have hard coded username and password checking. I would like to use a database, and therefore want to inject the data layer into my class. If I change the constructor to take a parameter, it throws an exception "No parameterless constructor defined for this object".
This is the example I based my code off: https://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx I added a constructor with an interface:
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
public MyServiceAuthorizationManager (IMyDataLayer mdl)
{ ...
Custom "Basic" Authentication for my WCF services. REST and RIA. Possible?
What you probably did is configure your manager class in a behavior of your configuration file (as the MSDN article shows):
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceAuthorization serviceAuthorizationManagerType="Samples.MyServiceAuthorizationManager,MyAssembly" />
</behavior>
</serviceBehaviors>
In that case WCF is completely in control over the creation of this type; not Simple Injector. This means that it requires a default constructor.
The first solution that comes to mind is to make that class a Humble Object and let it delegate to the real authentication logic that you place into a real service. This basically means that your Humble Object does nothing more than calling into the container to resolve the real service and call its appropriate method. Resolving should be done inside the Humble Object's class and the 'real' service should not be cached.
Another option is to configure your manager from code (as MSDN also shows) by resolving it from the container and assigning it to WCF:
serviceHost.Authorization.ServiceAuthorizationManager =
container.GetInstance<MyServiceAuthorizationManager>();
But care must be taken here, because the manager now becomes a singleton because WCF will hold on to it forever. Don't do this unless all its dependencies are singleton as well. Make sure you register your manager explicitly in the container as singleton, so the container can check for captive dependencies for you when you call Verify
.