How to inject dependencis into WCF Attribute with Simple Injector - wcf

I have a bunch of WCF services that works with REST and SOAP. I have created an WCF attribute who checks if the current httpcontext exists, if exists it use cookie authentication, other way it use custom WCF authentication.
My attribute looks like this:
Public Class AuthRequired
Inherits Attribute
Implements IOperationBehavior, IParameterInspector
Public Sub AddBindingParameters(operationDescription As OperationDescription, bindingParameters As Channels.BindingParameterCollection) Implements IOperationBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(operationDescription As OperationDescription, clientOperation As ClientOperation) Implements IOperationBehavior.ApplyClientBehavior
End Sub
Public Sub ApplyDispatchBehavior(operationDescription As OperationDescription, dispatchOperation As DispatchOperation) Implements IOperationBehavior.ApplyDispatchBehavior
dispatchOperation.ParameterInspectors.Add(Me)
End Sub
Public Sub Validate(operationDescription As OperationDescription) Implements IOperationBehavior.Validate
End Sub
Public Sub AfterCall(operationName As String, outputs() As Object, returnValue As Object, correlationState As Object) Implements IParameterInspector.AfterCall
End Sub
Public Function BeforeCall(operationName As String, inputs() As Object) As Object Implements IParameterInspector.BeforeCall
' IDS is the custom authentication service.
If IDS.Usuario Is Nothing Then
If HttpContext.Current Is Nothing Then
Throw New SecurityException("Las credenciales no son válidas para esta operación o no fueron provistas.")
Else
Throw New WebFaultException(Of String)("ACCESO DENEGADO. REVISE SUS CREDENCIALES.", Net.HttpStatusCode.Forbidden)
End If
End If
End Function
End Class
So, my question is how can I inject dependencies into this attribute using Simple Injector? I google for a while but the only thing I found was for Ninject, or inject filters on WebAPI.
Cheers!

You can't do constructor injection into attributes, because it is the CLR who is in control over the creation of attributes; not the DI library. Although you could initialize/build-up attributes after they have been created and inject dependencies using property injection, this is very risky for the following reasons:
Many frameworks cache attributes, which make them effectively singletons. This will cause Captive Dependencies in cases the dependencies themselves aren't singletons themselves.
It will be hard to impossible to let the container verify object graphs that start from the attributes, which might cause a false sense of security when verifying and diagnosing the container's configuration.
Instead, a much better approach is to either make attributes either passive or humble objects.
With a humble object, you extract all logic out of the attribute into its own service. The only code that will be left in the attribute is a call to your container or Service Locator to resolve that service and you call the method. This might look like this (excuse my C#):
public class AuthRequiredAttribute : Attribute, IOperationBehavior
{
public object BeforeCall(string operationName, object[] inputs) {
var checker = Global.Container.GetInstance<IAuthorizationChecker>();
checker.Check();
}
}
// Attribute's logic abstracted to a new service. This service can be
// registered, verified, diagnosed, and tested.
public class AuthorizationChecker : IAuthorizationChecker
{
private readonly IDS authenticationService;
public AuthorizationChecker(IDS authenticationService) {
this.authenticationService = authenticationService;
}
public void Check() {
if (this.authenticationService.Usuario == null) {
if (HttpContext.Current == null) {
throw new SecurityException();
} else {
throw new WebFaultException<string>();
}
}
}
}
This requires you to expose the container in a way that your attributes can resolve the services they need. Advantage of this is that it is easy implemented, quite clean. Downside is that that you have to fall back to the Service Locator anti-pattern to get this working, and you have to make sure that your service is registered, because the container won't warn about this and this will, therefore, fail at runtime instead of during application startup of inside an integration test that calls container.Verify().
The second option is using passive attributes. This is especially useful when you have multiple of these attributes. This article describes the basic idea behind passive attributes and gives an example how to implement this in Web API. WCF has different interception points, so applying this to WCF requires a different implementation, but the concept stays the same.

Related

How to access Request.Properties outside of Web API Controller

I'm setting a Property on Request.Properties inside a DelegatingHandler after I pluck some data out of a header on an incoming request to a Web API.
This all works fine. I can also access Request.Properties from within the controller as well as in my Action and Exception filters. However, I also need to access this data from outside of the controller (I call a business layer class from the controller). It is data I want to include in some logs in other places,
I can see HttpContext.Current from this class, and I can see the original header from here, so I guess I could pluck it out again, but since I have already done this and put it in the Properties it seems to make more sense to get it from there. However, I don't seem to have access to the Request.Properties from anywhere else.
If this isn't the right way to do this, how else would I pass around this per-request data so that it was accessible from anywhere on the stack in Web API?
I also need to access [Request.Properties] data from outside of the controller (I call a business layer class from the controller). It is data I want to include in some logs in other places... However, I don't seem to have access to the Request.Properties from anywhere else. If this isn't the right way to do this, how else would I pass around this per-request data so that it was accessible from anywhere on the stack in Web API?
You can get it from HttpContext.Current, though it is less than ideal. Keep in mind that if any other non-web applications consume the same business layer, then HttpContext.Current would be null. HttpContext.Current is only non-null when you are running in IIS, and an IIS thread is handling the execution of the request stack. If you ever plan to self-host the web api using OWIN without IIS, there will be no HttpContext.Current.
Personally, if the data really is important enough to be passed into the business layer to be logged, then I would just pass it to the business layer method:
public Task<HttpResponseMessage> SomeAction(SomeModel model) {
... other code
someBusinessLayerObject.SomeMethod(arg1, arg2, Request.Properties["myHeaderKey"]);
}
...If you need other values from Request.Properties, then you can just pass the whole dictionary to the methods that will end up using its values.
A third option if you are using an inversion of control container would be to add some kind of scoped object dependency class and put the data in there. Then constructor inject it into your business layer class:
public interface IHaveRequestData {
IDictionary<string, object> Properties { get; set; }
}
public class RequestData : IHaveRequestData {
public IDictionary<string, object> Properties { get; set; }
}
// ioc registration pseudocode
iocContainer.Register<IHaveRequestData, RequestData>(Lifetime
.WhateverYouNeedSoThatOneOfTheseGetsCreatedForEachWebRequest);
public class SomeController : ApiController {
private readonly IHaveRequestData RequestData;
public SomeController(IHaveRequestData requestData) {
RequestData = requestData;
}
public Task<HttpResponseMessage> SomeAction() {
// you may even be able to do this part in an action filter
RequestData.Properties = Request.Properties;
}
}
public class SomeBusinessLayerComponent {
private readonly IHaveRequestData RequestData;
private readonly ILog Log;
public SomeBusinessLayerComponent(IHaveRequestData requestData, ILog log) {
RequestData = requestData;
Log = log;
}
public Task SomeMethod() {
Log.Info(RequestData["myHeader"]);
}
}

Autofac - Resolve specific implementation from registered assembly

I'm using Autofac and want to resolve the correct implementation of the current assembly
I have a DataContextFactory Interface and Class:
Public Interface IDataContextFactory
Inherits IDisposable
Function GetDataContext() As IDataContext
End Interface
and the Implementation of the Interface
Public Class CDataContextFactory
Implements IDataContextFactory
Private m_oDbContext As IDataContext
Public Sub New(ByVal i_oDbContext As IDataContext)
m_oDbContext = i_oDbContext
End Sub
Public Function GetDataContext() As CoreData.IDataContext Implements CoreData.IDataContextFactory.GetDataContext
Return m_oDbContext
End Function
End Class
So now I have in every registered assembly different IDataContext Implementations. For example I have an assembly called ReportData with the data context
Public Class CReportDataContext
Inherits DbContext
Implements IDataContext
---
End Class
And also one implementation inside an other Assembly CommonData
Public Class CFacadeDataContext
Implements IDataContext
---
End Class
Then I have in every Assembly an implementation of my IRepository. For example
Public MustInherit Class CBaseReadRepository(Of T As {IEntity, Class})
Implements IReadRepository(Of T)
Private m_oDataContextFactory As IDataContextFactory
Private m_oDataContext As IDataContext
Protected ReadOnly m_oObjectDataSet As CQuery(Of T)
Public Sub New(ByVal i_oDataContextFactory As IDataContextFactory)
m_oDataContextFactory = i_oDataContextFactory
m_oObjectDataSet = DataContext.ObjectDataSet(Of T)()
End Sub
----
End Class
So how can I solve that the DataContextFactory will resolve the CReportDataContext inside the Assembly ReportData and the CFacadeDataContext inside the Assembly CommonData
Here is my ContainerBuilder registration:
Dim builder As New ContainerBuilder()
Dim oData = Assembly.Load("ReportData")
builder.RegisterAssemblyTypes(oData).Where(Function(t) t.Name.EndsWith("DataContext")).As(Of IDataContext) _
.AsImplementedInterfaces.SingleInstance
oData = Assembly.Load("CommonData")
builder.RegisterAssemblyTypes(oData).Where(Function(t) t.Name.EndsWith("DataContext")) _
.AsImplementedInterfaces().SingleInstance
builder.RegisterAdapter(Of IDataContext, IDataContextFactory)(Function(x) New CDataContextFactory(x))
Thanks
Autofac doesn't have built-in support for this sort of use case. Generally it's recommended that you try not to tie specific implementations to consumers because that breaks the whole IoC pattern - you may as well "new-up" the dependency type you need right in the class rather than injecting it.
If you absolutely must tie them together, you only have a couple of options. Neither is pretty, and both will require you to change the way you register things - you may not be able to do the RegisterAssemblyTypes assembly scanning like you do now.
First, you could use named registrations. When you register your IDataContext, you give it a name. When you register your consuming class, you tell the builder which named instance you expect to use.
builder.RegisterType<MyDataContext>().Named<IDataContext>("some-name");
var contextParam = ResolvedParameter.ForNamed<IDataContext>("some-name");
builder.RegisterType<MyConsumer>().As<IConsumer>().WithParameter(contextParam);
Second, you could register an expression rather than a type for the consumer:
builder.Register(c => new Consumer(new SomeContext())).As<IConsumer>();
Finally, you could create a special module that does the work of figuring out which assembly the consumer is coming from and try to match it to a corresponding IDataContext. This is more "automatic" but is a lot more complex. A stub might look like this:
public class DataContextModule : Autofac.Module
{
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry,
IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
}
public static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
Type typeBeingResolved = e.Component.Activator.LimitType;
// TODO: Do some reflection to determine if the type takes an IDataContext
// in the constructor. If it doesn't, bail. If it does...
var parameter = new ResolvedParameter(
(p, i) => p.ParameterType = typeof(IDataContext),
(p, i) => {
// TODO: Use i (the IComponentContext for the resolution)
// to locate the right IDataContext from the list of registrations,
// resolve that one, and return it so it can be used in
// constructing the consumer object.
});
}
}
Like I said, not pretty.
If you have the ability to influence your design, it might be easier to make marker interfaces, like:
public interface ICoreDataContext : IDataContext { }
And then in your constructors take the specific interface:
public SomeClass(ICoreDataContext context);
That way type resolution would just work. (Marker interfaces aren't the greatest pattern in the world, either, but it's arguably better than tying individual implementations of things to specific consuming types.)

WCF declarative security using CodeAccessSecurity

I'm planning to use custom permission-based declarative authorization mechanism based on CodeAccessSecurity. In order to implement it I've created following subclass derived from CodeAccessSecurityAttribute:
[Serializable]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class RequirePermissionAttribute : CodeAccessSecurityAttribute {
private static readonly IPermission _deny = new SecurityPermission(PermissionState.None);
private static readonly IPermission _allow = new SecurityPermission(PermissionState.Unrestricted);
public RequirePermissionAttribute(SecurityAction action)
: base(action) {
}
public string Permission { get; set; }
public override IPermission CreatePermission() {
if (User.HasPermission(Permission))
return _allow;
else
return _deny;
}
}
I use it this way:
[ServiceContract]
public class Service {
[OperationContract]
[RequirePermission(SecurityAction.Demand, Permission = "GetArbitaryProduct")]
public User GetProduct(string name) {
return _productRepository.Get(name);
}
}
And I expected that if CreatePermission method returns _deny access to GetProduct will be restricted. But it looks that CodeAccessSecurity doesn't work this way. Do I have to throw an exception to restrict access properly? Or maybe there is more elegant way to achieve that?
The CLR mechanism that wires up permission verifications based on a CodeAccessSecurityAttribute subclass instance will only prevent execution of the target method if an exception is thrown when the permission returned by CreatePermission() is evaluated. Since you're specifying SecurityAction.Demand as the permission action, this means that the permission's Demand() method must throw in order to avoid execution of the target method.
There are plenty of other ways to handle authorization scenarios, many of which you might find more "elegant". However, before you start looking for alternate approaches, it would be best to consider what behaviour your service caller should observe when authorization is denied. Do you want the method to succeed but return null, or would you prefer to return a fault? If the latter, do you want it to be a typed fault or not?

WCF - Return object without serializing?

One of my WCF functions returns an object that has a member variable of a type from another library that is beyond my control. I cannot decorate that library's classes. In fact, I cannot even use DataContractSurrogate because the library's classes have private member variables that are essential to operation (i.e. if I return the object without those private member variables, the public properties throw exceptions).
If I say that interoperability for this particular method is not needed (at least until the owners of this library can revise to make their objects serializable), is it possible for me to use WCF to return this object such that it can at least be consumed by a .NET client?
How do I go about doing that?
Update: I am adding pseudo code below...
// My code, I have control
[DataContract]
public class MyObject
{
private TheirObject theirObject;
[DataMember]
public int SomeNumber
{
get { return theirObject.SomeNumber; } // public property exposed
private set { }
}
}
// Their code, I have no control
public class TheirObject
{
private TheirOtherObject theirOtherObject;
public int SomeNumber
{
get { return theirOtherObject.SomeOtherProperty; }
set { // ... }
}
}
I've tried adding DataMember to my instance of their object, making it public, using a DataContractSurrogate, and even manually streaming the object. In all cases, I get some error that eventually leads back to their object not being explicitly serializable.
Sure, write a wrapper class that has all of the same public properties available and simply put "get { return internalObject.ThisProperty; }. Decorate the wrapper class so that it works with WCF.
Another option is to write a Proxy class which mirrors the properties of the type you wish to use exactly, and return that via WCF.
You can use AutoMapper to populate the proxy object.
This approach has the advantage that your service's consumers don't need to take a dependency on the third party library in trying to use it.

WCF service with multiple implementations of dependency

I have a WCF service that will be called from a various clients.
Internally the WCF service uses an ISomething. There are multiple implementations of this interface and I need some clients to use one implementation and other clients to use a different implementation.
In addition, I am using Unity and an IoC container. I would typically set up a custom factory to allow the wcf service itself to be resolved along with its dependency graph, but if I have multiple implementations of a dependency, I do not think I can go with this approach and would have to resort to resolving the ISomething within the service (effectively using Unity as a service locator) which is not ideal.
So I need to work out
(1) how to specify which implementation of ISomething a client needs (eg. use a header, pass implementation string in each method, host multiple endpoints etc.)
(2) how Unity fits in?
One option is to write a Decorator that performs the selection for you:
public class RoutingSomething : ISomething
{
private readonly ISomeContext ctx;
private readonly ISomething s1;
private readonly ISomething s2;
private readonly ISomething s3;
public RoutingSomething(ISomeContext ctx)
{
this.ctx = ctx;
// An even better design would be to inject these too
this.s1 = new BarSomething();
this.s2 = new BazSomething();
this.s3 = new QuxSomething();
}
// Assuming ISomething has a Foo method:
public void Foo()
{
if(this.ctx.Bar())
{
this.s1.Foo();
return;
}
if(this.ctx.Baz())
{
this.s2.Foo();
return;
}
if(this.ctx.Qux())
{
this.s3.Foo();
return;
}
}
}
You could generalize this so that ISomeContext is simply an Abstract Factory of ISomething. This then begins to turn into the general solution to varying dependencies based on run-time context.
You can now register RoutingSomething in Unity in addition to your other components. When the container resolves the service, it'll inject an instance of RoutingSomething into it.