How to provide dependency injection via StructureMap for a custom role provider with WCF? - wcf

We're going to be using a custom role provider with WCF. The overridden method GetRolesForUser will require the use of an already existing RoleRepository.
Now, with a run-of-the-mill class, we'd construct it using StructureMap and the RoleRepository dependency would be injected via the constructor.
However, it's WCF that does the constructing of the the custom role provider class and that's 'done' declaritavely via the roleManager attribute in the web.config.
I don't really want to hard-wire the RoleRepository depndency into the custom role probvider class but it's looking like I'll have to.
Any ideas?

The RoleProvider and related types are legacies of ASP.NET which are infamous for not being DI-friendly. They require a default constructor and there are no hooks offered to initialize them. It sucks, but that's the way it is.
In such situations, the best remedy is to implement the RoleProvider as a Humble Object. In other words, the RoleProvider must wire up all dependencies, but from there, it delegates all implementation to your own open and extensible API.

Related

User scoped dependencies in a custom ASP.NET Core Action Filter?

According to the official documentation here:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#authorization-filters
To implement a custom ActionFilter in ASP.NET Core I have three choices:
SeviceFilterAttribute
TypeFilterAttribute
IFilterFactory
But for all three it is stated that:
Shouldn't be used with a filter that depends on services with a lifetime other than singleton.
So how can I inject scoped services in my custom ActionFilter? I can easily get a scoped service from the current HttpContext like this:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
ISubscriptionHelper subscriptionHelper =
actionContext.HttpContext.RequestServices
.GetRequiredService<ISubscriptionHelper>();
}
But then I am wondering if I am doing something wrong? What is the correct way to depend on scoped services in a custom ActionFilterAttribute?
Resolving services from the HttpContext.RequestServices will correctly resolve scoped and transient instances without causing any problems such as Captive Dependencies. In case resolved components implement IDisposable, they will be disposed of when the request ends. ASP.NET Core passes on the current HttpContext object to filter's OnActionExecuting method and that HttpContext gives access to the DI Container.
This is completely different from injecting those services into the constructor, because the action filter will be cached for the lifetime of the application. Any dependencies stored in private fields will, therefore, live as long as that filter. This leads to the so called Captive Dependency problem.
Code that accesses the DI Container (the HttpContext.RequestServices is your gateway into the DI Container) should be centralized in the infrastructure code of the startup path of the application—the so called Composition Root. Accessing your DI Container outside the Composition Root inevitably leads to the Service Locator anti-pattern—this should not be taken lightly.
To prevent this, it is advised to keep the amount of code inside the action filter as small as possible and implement the filter as a Humble Object. This means that preferably, the only line of code inside the filter is the following:
actionContext.HttpContext.RequestServices
.GetRequiredService<ISomeService>() // resolve service
.DoSomeOperation(); // delegate work to service
This means all (application) logic is moved to the ISomeService implementation, allowing the action filter to become a Humble Object.

MVC4, UnitOfWork + DI, and SimpleAuthentication .. how to decouple?

I'm currently working on an MVC4 project, i make use if Ninject to inject a UnitOfWork into my controllers, and I'm using UnitOfWork + Generic Repository pattern.
I don't like VS2012 MVC4 template because it directly uses database access (db initialization, for example).
My project divides in:
a UI project (the mvc4 application), with Forms Authentication
a Domain project (the db entities, the repositories, the UnitOfWork interface plus two UnifOfWork implementations, one with MOQ and one with EF; they are injected into UI controllers via Ninject).
I looked at this example:
http://kevin-junghans.blogspot.it/2013/03/decoupling-simplemembership-from-your.html
related to this question
SimpleMembership - anyone made it n-tier friendly?
And now I have some question:
How can i inject my UoW here? WebSecurity class is static, there is no contructor, it directly instantiate the UoW to perform activities on db ...
I always have to initialize WebMatrix to directly access DB? This piece of code:
public static void Register()
{
Database.SetInitializer<SecurityContext>(new InitSecurityDb());
SecurityContext context = new SecurityContext();
context.Database.Initialize(true);
if (!WebMatrix.WebData.WebSecurity.Initialized)
WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection("DefaultConnection",
"UserProfile", "UserId", "UserName", autoCreateTables: true);
}
breaks my decoupling with the Domain .. how can i make WebSecurity using my UnitOfWork for example? what is the best practice?
How can i store additional data (for example, EmailAddress and so on) and retrieve it, without performing a Database query everytime i have to access the User profile? Something like the old CustomPrincipal ... Custom principal in ASP.NET MVC
Thank you!
You have a lot of questions here Marco. Let me take a stab at them.
How to inject a UOW
Static classes and dependency injection do not mix well, as pointed out in this QA. When I first went through this exercise of decoupling SimpleMembership the concentration was just on decoupling from the domain, as discussed in the article you referenced. It was just a first step and it can be improved on, including making it easier for dependency injection. I debated whether to make WebSecurity static or not and went with static because that is how the original SimpleMembership is implemented, making it a more seamless transition for user of the SimpleSecurity. SimpleSecurity is an open source project and contributions are welcome. Making it non-static would not be difficult and probably makes sense in the long run. Once it is made non-static we could use a Factory pattern to create the UnitOfWork and inject the appropriate Factory.
Why do I have to Register WebSecurity?
SimpleSecurity is just a wrapper around the WebMatrix WebSecurity classes, which require initialization. The Register method just makes sure that WebMatrix is initialized and initializes our database. I disagree that having this method call in the Globa.asax couples it with the Domain in any way. Having it work with your UnitOfWork should have nothing to do with the Application Domain, or with having to call a Register method at application start-up.
How can I store additional data (ex: email) and retrieve it, without performing a database query every time?
This is actually accomplished quite easy in .NET 4.5 by using ClaimsPrincipal. All principals in .NET 4.5 inherit from ClaimsPrincipal, which allows you to store information in the principal as claims. Claims are basically key value pairs that let you store any type of data on the user. For example in ASP.NET the roles for a user are stored as claims. To add your own claims you need to do something called claims transformation. Then to retrieve the information you can create a custom claims principal. Adding this to SimpleSecurity would be a nice feature.

WCF and Ninject

within our per-session WCF services hosted in ISS, we would like to use Ninject to IOC different data access component through the interface.
Where would be the best place to declare the binding once? is it in Application_Start of Global.asax?
If it is, how could I obtain the instance through the inferface from Ninject?
I know in StructureMap, we can call something like ObjectFactory.GetInstance()?
What is the equivalent in Ninject?
Thanks
I assume you have looked at the official WCF extension? I usually define my own service factory (referenced in the .SVC file) and reference my Ninject module from there.
As for getting an instance from an interface (i.e. the opposite of having it injected), you do so via the kernel. (You can always have an instance of IKernel injected into any of your classes by adding it to your constructor.) Once you have it, you just use:
kernel.Get<IYourInterface>();

Validating parameters with WCF, Unity and VAB

I am developing an application that exposes a WCF service using the Message/Response pattern for service methods. The application is using Unity 2.0 for dependency injection and the Validation Application Block from MS Patterns & Practices. I've already gotten Unity tied into WCF using a custom HttpModule I picked up from several website a while back and everything works great.
In my service interface I have a method such as:
DoSomethingResponse DoSomething(DoSomethingRequest request)
I can easily attach VAB attributes to the service contract to verify that 'request' is never null but I also want to validate the contents of the request object.
To do this, I inject the validator into the DoSomethingRequest constructor and include an internally scoped IsValid property which handles interacting with the VAB validator. Unfortunately, this constructor doesn't get called because WCF deserializes the object and constructors aren't used.
Without getting into the merits of having the request object be a simple DTO versus having some server-side business logic, is there a way to cleanly inject dependencies into an object passed into WCF service as an argument?
If I'm understanding your issue correctly, you have properties on DoSomethingRequest that are instances of some other classes (data contracts) and you want to validate your data contracts as well? Is there some reason you can't just apply validation attributes to your data contract classes as well? This is the approach I've used when using WCF with VAB integration and it's worked out quite nicely.
So it turns out that adding the validation attributes to my DataContract actually works with no additional code. Unfortunately, it doesn't work if validation is defined in the app's config file (app.config or web.config).
As a result, I've stripped out the constructor injection and IsValid property on my DataContract (request object) which makes it more of an annotated DTO which I think is preferred anyway. I only wish that it would work the same with the XML configuration.

Can a custom UserNamePasswordValidator add things to the WCF session?

Related to this question, I'm instantiating a connection to our internal API inside my custom UserNamePasswordValidator. Can I stash this somewhere so that I can use it in future calls in that user's session?
This is similar to this question, but I'm not using IIS, so I can't use HttpContext.Current (or can I?).
Update: Some context: our internal API is exposed via a COM object, which exposes a Login method. Rather than have a Login method in my service interface, I've got a custom UserNamePasswordValidator, which calls the Login method on the COM object.
Because instantiating the COM object and logging in is expensive, I'd like to re-use the now-logged-in COM object in my service methods.
Yes, it can. You'll need:
a custom ServiceCredentials implementation that returns a custom SecurityTokenManager.
a custom SecurityTokenManager implementation that returns a custom CustomUserNameSecurityTokenAuthenticator.
your custom CustomUserNameSecurityTokenAuthenticator needs to override ValidateUserNamePasswordCore, and should add a custom implementation of IAuthorizationPolicy.
your implementation of IAuthorizationPolicy should implement Evaluate, at which point it can start putting things in the WCF context.
replace the evaluationContext["PrimaryIdentity"] value with a PasswordIdentity or a custom IIdentity.
replace the evaluationContext["Principal"] value with a PasswordPrincipal or a custom IPrincipal.
update the evaluationContext["Identities"] collection to replace the GenericIdentity instance with your custom instance.
By doing this, you can have a custom IPrincipal implementation with some extra information in it.
For more details, see this.
UserNamePasswordValidator is absolutely out of all WCF contexts. It is only used to validate user name and password. Can you futher explain your problem?
Edit:
I guess COM object is instantiated for each session, isn't it? Otherwise wrapping COM into singleton should solve your problem. If you need to have per session COM object shared between validator and service instance you will need some cache or registry - something which is outside both validator and service and can be called from both of them.