Force WCF to call a method on every request before entering actual function - wcf

I have a RESTful WCF service with many different functions. For each function I need to call an authentication method that I have written. I can manually call this method on every request but I was looking for a way to force the WCF engine to call this method before these functions are entered. Does anyone know if this is possible?
Cheers

You could use the "Custom Behavior" approach.
You would need to write a Class that implements IDispatchMessageInspector. The following MSDN magazine article gives a nice explanation of this: Extending WCF with Custom Behaviors (link points to Wayback Machine cached copy; downloads likely don't work).

To force WCF REST Service to first call a method especially if it's for authorization
customize/override CheckAccessCore method of System.ServiceModel.ServiceAuthorizationManager
refer: http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx

If it's for authorization, can't you use the built in services?
For instance, there is the PrincipalPermission attribute. Does that help in your case?

You could think about creating a WCF routing service. You would call a fixed endpoint - your authentication method - and then from there on, route your calls to the actual methods, based on some indication in the request.
For .NET 4, the Routing Service functionality will be included into WCF out of the box.
What I don't know is how that all matches REST, though.

I came across this post, while searching for the same thing.None of the answer's were simple/quick solution so if you just want a function to be called before every method then you can do what i just did:
I created a zero argument constructor:
public class myService : ImyService
{
myService ()
{
ConnectToDatabAse();
FunctionYouWantToCallBeforeEveryMethodCall();
//Add here more
}
}

Related

Using WCF Extensibility at Client Side

I am using a web application as a client to invoke WCF methods using proxy.
For each request being made by client object, I need to populate few properties (declared inside request class)
Is it possible to hook a method, just before making the actual web service call.
I can't modify service code right now, Can WCF extensibility points could be leveraged in this case?
Thanks for your help.
If you want to change the properties of the method parameters, you can use an IParameterInspector to do that, since at that point you'll get an array with all parameters to be sent to the server.
If you need to change other parts of the request (such as transport or SOAP headers), an IClientMessageInspector may be the best way to go.
For more information on many extensibility points at the client side, you can check the blog series at http://blogs.msdn.com/b/carlosfigueira/archive/2011/03/14/wcf-extensibility.aspx.

WCF Callback implementation function never gets called

I am designing a WCF service with callback, but my implementation of the callback function never gets called. And I am confused about the generated service proxy, so please help.
Here is the scenario: in the server side, I defined the service interface IMyService and callback interface IMyServiceCallback, I also implemented the IMyService in the server project. Besides the server project, I surely have another client project, to which I added the service reference in VS. And I implemented the IMyServiceCallback interface on the client side. So here comes the problem: when I am debugging it, the function never goes into my implementation of IMyServiceCallback and of course the desired result never comes out.
And this is I where I got confused: when I added the service reference in the client side, it actually generated three interfaces on the local: IMyService, IMyServiceCallback, and IMyServiceChannel plus the client proxy class. And in my local implementation of IMyServiceCallback, I declared the class to implement the local IMyServiceCallback interface, not the one from service side. Could this be the problem? Why is there two declarations of the interface under different projects(and hence different namespaces)? The reason I implement the client side interface is, if I implemented from the server side interface, it would give the error: "InstanceContext provided to the ChannelFactory contains a UserObject that does not implement the CallbackContractType error" when I tried to call the service. And another confusing part is, on the server side if I declare the callback interface name as IMyCallback, or anything else, instead of IMyServiceCallback, the generated interface on the client side would still be IMyServiceCallback, which is the name of the service interface plus the suffix "Callback". And in this situation I also got the "InstanceContext provided to the ChannelFactory contains a UserObject that does not implement the CallbackContractType error".
I guess there is something that I misunderstood about the "add service reference" and how I should implement the interface(which one to implement). Could anyone help me? Thanks!
Updated:
I somehow fixed the problem. Firstly, the two declarations is fine is desired. The local client will need to implement the local interface, which is generated when adding the service reference. And my problem was that I also defined a DataContract but the generated reference file didn't have it. It could either because I had added the assembly of the service project as reference(somebody said in this case add service reference will not generate the Datacontract) or because I was missing DataMember attribute. But anyway, after I fixed both parts, the function is working now.
When you "Add Service Reference" and generate a proxy, it is totally separate from your service implementation. Remember, you may be consuming a service that you have not written and do not have access to the service source code.
The client code should use the client generated interfaces. If you change your service, you need to regenerate the proxy.
If you find this too messy, and you know you will always control both ends, you can share the service interfaces in a common assembly and generate a proxy class at runtime using DuplexChannelFactory.CreateChannel().
As for your problem, I can only assume you are not registering your callback properly. This is covered here.
if you want publish , you must implement IMyServiceCallback and IMyService together in same project.
if only subscribe , you must implement IMyServiceCallback interface
I fixed the issue when my callback instruction was embedded in a function call.
I learned that placing the callback in just a method that does not return a result works fine.
However, when the callback instruction is placed within a function I ran into timeout issue.
I resolved it by using a backgroundworker thread within the function being invoked:
public static IMyServiceCallback Callback;
.
.
.
TaskStateData taskStateData = GetSomeData();
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (se, ev) =>
{
Tuple<OperationContext, TaskStateData> data = ev.Argument as Tuple<OperationContext, TaskStateData>;
var operationContext = data.Item1;
if (operationContext != null)
{
Callback = operationContext.GetCallbackChannel<IMyServiceCallback>();
Callback.OnCallBack();
}
};
Tuple<OperationContext, TaskStateData> payload = new Tuple<OperationContext, TaskStateData>(OperationContext.Current, taskStateData);
backgroundWorker.RunWorkerAsync(payload);

WCF service calls includes same information in every call

I have a web service that will be consumed by some application (web site currently).
The calls are almost all specific to a certain client but still the same. So one call might be getAllFoo() but I would need some parameter to say from which client the Foo is.
It would become bothersome quickly if I just add a standard parameter to all calls so I was hoping to do it a little bit DRY and automatic. Something that would be included in all service calls.
Is IDispatchMessageInspector the right thing for me here? What kind of info could that include and can I access that info inside the methods?
Should I create some sort of attribute perhaps for the calls?
If anyone could point me towards a solution for this it would be great.
Edit
Another solution I'm thinking off.
Where the service call to a specific client happens on the consumer side, it will be known at instanceCreation so I could instance the ServiceClient with a known client.
Could I use this solution for the ClientBase<> extender somehow.
Let's say I'm serving Domain1 (let's call the client Domain to not confuse it with a serviceclient/consumer) I create a InformationProvider consumer side that has a ClientBase<IInformationService> field. I ensure that the DomainName (domain1) is set at construction so I could parhaps do the same thing when instancing the ClientBase<IInformationService> so It somehow let's the service know what domain I'm calling for.
I'm just still learning about WCF so I'm not sure how one would do this.
I can understand that you want to keep you solution simple and tidy, but ultimately - as you say yourself -
... I would need some parameter to say from which client...
The obvious and simplest solution is to include a client parameter on all your service calls where it is required. Surely there'll be service calls that don't require the client parameter, and in those cases you don't need to include the parameter.
You may be able to do something clever where a client identifier is passed discreetly under the covers, but beware of doing unnecessarily clever things. I would pass the client as a simple parameter because it is being used as a parameter. Two reasons come to mind:
if someone maintains your code they quickly understand what's going on.
if someone needs to use the service it is obvious how to use it.
A possible pattern:
Make sure you service instantiates per session. This means you'll have to use wsHttpBinding, netTcpBinding, or a custom binding as http does not support sessions.
Always call an initialization operation when each session is instantiated that sets the client id for that service.
Put this initialization operation inside a constructor for a proxy.
The steps involved would be something like this:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
private int clientId;
public void StartUp(int clientId)
{
this.clientId = clientId;
and then client side, assuming you use the generated proxy, wrap the client inside another proxy.
public class ExtendedClient : MyServiceClient
{
public ExtendedClient(int clientid) : base()
{
this.StartUp(clientid);
}
Now you should instantiate the ExtendedClient, it will create the channel and prime the service by delivering the client id.
I would personally prefer to simply send the client id for each service call, but if you are able to use a session-able binding then this should work.
Just some information on WCF for you. If you have a stateless service, then you'll need to include the client as a parameter in every service call. This does not mean you need to include the client everywhere throughout your code - you could, for example, retrieve it inside the ClientBase constructor. But you will need to add it to every OperationContract and all the service implementations.
The alternative is to have a stateful service - the instance that you first use will remain for you to reuse (except for timeouts / exceptions). In this case you can potentially send the client just once, and then the service will know about the client for subsequent calls. This is the pattern described above. It means that you cannot use http binding. I believe that by doing this you're only increasing the potential for problems in your application (stateful services, having to ensure the initialization operation completes, more service calls being made).

Inject behavior into WCF After or During identification of WebGet Method to call

I am trying to solve a problem where i have a WCF system that i have built a custom Host, Factory host, instance providers and service behaviors to do authentication and dependency injection.
However I have come up with a problem at the authorisation level as I would like to do authorisation at the level of the method being called.
For example
[OperationContract]
[WebGet(UriTemplate = "/{ConstituentNumber}/")]
public Constituent GetConstituent(string ConstituentNumber)
{
Authorisation.Factory.Instance.IsAuthorised(MethodBase.GetCurrentMethod().Name, WebOperationContext.Current.IncomingRequest.Headers["Authorization"]);
return constituentSoapService.GetConstituentDetails(ConstituentNumber);
}
Basically I now have to copy the Call to IsAuthorised across every web method I have. This has two problems.
It is not very testable. I Have extracted the dependecies as best that I can. But this setup means that I have to mock out calls to the database and calls to the
WebOperationContext.
I Have to Copy that Method over and over again.
What I would like to know is, is there a spot in the WCF pipeline that enables me to know which method is about to be called. Execute the authorisation request. and then execute the method based on the true false value of the authorisation response.
Even better if i can build an attribute that will say how to evaluate the method.
One possible way to do what you want might be by intercepting requests with a custom IDispatchMessageInspector (or similar WCF extension point).
The trick there, however, is that all you get is the raw message, but not where it will be processed (i.e. the method name). With a bit of work, however, it should be possible to build a map of URIs/actions and the matching method names (this is how you'd do it for SOAP, though haven't tried it for WebGet/WebInvoke yet).

WCF Service public class available to consuming application

I am writing a WCF Service and inside the service application have a couple of classes... I want these to be available to the consuming application but it won't actually pass them back as a parameter, rather it will add them into a object array and then pass them back. Seems the only way I can find to make available to .NET App is to have them as a parameter in a service method.
Am I missing something obvious?
Thanks
Found answer, sorry:
add to IService
[ServiceKnownType(typeof())]