How to pass additional data to Castle interceptor? - c#

I have a class that is exposed as a WCF service. The class lifetime is managed by Castle Windsor, which attaches a number of interceptors like logging aspect and permission aspect. With WCF I can pass some additional data in message headers, like the username or a userSessionId. Then on the server side the Permission interceptor can use OperationContext.Current.IncomingMessageHeaders and read which user is making the call. Then it can allow the invocation to proceed or throw an exception.
The problem is that now I want to ditch WCF and replace it with something else (RabbitMQ to be excact). How can I get a similar functionality to WCF OperationContext.Current, but without WCF? Or otherwise add some additional data to an IInvocation, so the interceptor would be able to read? The interceptor must be transparent to the rest of the world as usual.

Related

WCF with Castle Windsor error handling to Application Insights

I have the following scenario:
I am using castle windsor component activator to create and destroy the scope for the WCF.
I have a WCFServiceActivator that extends Castles DefaultcomponentActivator and implements the InternalCreate and InternalDestroy to call BeginScope and Scope.Dispose() for the service.
WCF session is defined as per request
I implemented a ErrorHandler class and defined the ProvideFault and HandleError
In the handle error I want to send exception metrics to ApplicationInsights, but when I use castle to provide some factory I get no scope, since it was already destroyed after the provide value runs and the response is sent to the client.
Basically when the HandleError method executes, the scope created by the activator was already destroyed due to the perWcfRequestLifecycle.
I was wondering on maybe creating a new Castle LifecycleStyle that wraps a higher layer of the wcf but I don't know if it is possible.
Does someone have a solution for this scope issue?

Authentication via headers in WCF REST service

I am new to WCF services and currently testing out things.
I have got a little REST API, which has several methods. Some of them require a user context (session), some others don't. At login, each user gets a session token. The client should supply this token and his user ID on every request via HTTP headers.
At the moment, I wrote a method for getting those two headers and validate the session, calling it on every method which will need a user context. This seems kinda nasty if the API gets bigger.
Is there a better approach for doing this?
You can leverage of following solutions:
Custom class deriving IClientMessageInspector/IDispatchMessageInspector for client and service respectively. Then you add its instance to MessageInspectors. Advantage of having messageInspector is that it's applied to single endpoint so regardless of having many endpoints exposed (both SOAP and REST), messageInspector can be associated only with single one. Whenever message is either received or sent, AfterReceive or BeforeSent method is invoked respectively. There you retrieve headers and if token does not match any expected you can throw an exception. Such a way out provides separation between exposed contract and background checks such as token validation.
Custom class deriving IOperationInvoker. Within custom operation invoker you explicitly call method and thanks to it you can examine headers (OperationContext.Current.IncomingMessage) before any method gets invoced.
I brought up only concepts, extensive information and examples can be looked up on Internet.

Is RequestFilter Validation client dependent?

Should I expect Request Filter Validation (e.g. FluentValidation) to be triggered when instantiating a reference service via AppHostBase.ResolveService<>?
Thus far, I've only successfully received proper error responses to my C# application when using the typed clients (JsonServiceClient in this case specifically).
You are right. If you try use AppHostBase.ResolveService<T> it does not execute any of the registered request filters. Essentially it only resolves the Service from the AppHost dependancy container, you get back just the Service instance. Thus your validators aren't triggered.
ServiceStack v4:
As #mythz points out you can use the MQ entry point API of the HostContext to execute the call with the MQ request filters and thus have the validation run. To do this:
HostContext.ServiceController.ExecuteMessage(new Message<T>(requestDto), httpReq);
#mythz also notes you can execute a service using just a DTO, rather than having to determine the service and handling method to call, but in a similar fashion to AppHostBase.ResolveService<T> it doesn't trigger the request filters. Usage:
HostContext.ServiceController.Execute(requestDto, httpReq)
ServiceStack v3:
GetAppHost().Config.ServiceManager.ServiceController.ExecuteMessage(new Message<T>(requestDto), httpReq);

c# how to manage wcf service proxy lifecycle on client side?

I have written a WCF service with some regular functionality (add user, remove, search, update...). The implementation of this functionality is in entity framework (with sql DB).
Now I want to use it in the client side.
And I have some basic questions:
I have many calls to the WCF methods in the client side - should I try catch every time each call?
Every time I want to call a method, for example AddUser(User user), I need to make an instance of my service, like that:
WcfService client = new WcfService();
client.AddUser(user);
And in another place I write:
WcfService client = new WcfService(); //Again making a new instance...
client.UpdateUser(user);
Should I make one instance for all the application for my wcf service?
Or every time to make a new instance before I call to a method? (as in my example above).
Thanks very much !
In many cases, you want to reuse the same client proxy, as this connection method yields the best performance. Reusing the same proxy can be particularly beneficial if you use security features, which have a high initial security negotiation cost. Note: you surely need to check the state of the client proxy before using.
In the event that reusing the same client proxy is not an option, then consider using a ChannelFactory proxy that uses caching.
The following link provides a good explanation along with best practice recommendations:
http://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx
(i)You can make an instance one time for a service, and use the same client whenever you need to make a method call. if you are aborting or closing the connection then you need to create each time.
(ii)It is better if you use try catch methods in each methods, so it will be easy to close the connection and identify the exceptions.

.NET webservice client from WSDL

I have a WSDL from which I generated the implementation of ClientBase namely MyService
function void updateData(Data data){
BasicHttpBinding binding = new BasicHttpBinding();
// see there is naked username and password.
EndpointAddress address = new EndpointAddress("http://qa.farwaha.com/eai_enu/start.swe?SWEExtSource=WebService&SWEExtCmd=Execute&UserName=john&Password=johspassword");
MyService service = new MyService(binding, address);
try{
service.update(data);
}finally{
service.close();
}
}
Unfortunately, to call this web service I have to pass User name and password as shown in the code. so, my question is around best practices.
Given that its a Winform Application.
How memory / CPU intensive is creating MyService object?
If you suggest cashing the service, it will hold on to the EndpointAddress; which intern has a string with Username and Password. Which is not a good idea .. any work arounds?
If I keep the code as such, service object will be garbage collected .. and there will be no trace of user name or password (as soon as GC runs)
This is a sample code, I have User Object which stores password in SecureString and every time I have to access the password; I get string from SecureString in an instance private method, use it quickly and let it be garbage collected. I believe if I use a method something like above, it will be safe OR safe enough rather than holding on to reference of Service, What do you suggest !!
To your specific questions:
In your client code, what you're constructing are instances of lightweight proxy classes that wrap the channel infrastructure that serialize messages to/from the service's endpoints. As such, these client proxy classes are cheap and fast to construct because they don't generally do a great deal until you actually send something to the service. One thing to watch out for is when you call services which employ a more complex security scheme - establishing connections to such services can be costly and so it's worth caching or re-using such connections if you can.
"Any workarounds"? Nope! Alas, the service you're consuming is poorly designed - not only do they require username and password to be supplied as part of the service method invocation, but they require that you pass them in the clear over HTTP. You might want to ask them to AT LEAST provide an SSL endpoint so that the username and password can be secured during transit. Better still, they could implement basic-auth to allow you to acquire an HTTP auth cookie that you can attach to subsequent calls against their services.
Yes, the GC will eventually clean-up your proxy instances. Better still, you could wrap your instances in using statements to invoke the Dispose pattern and clean-up deterministically. See my Magic8Ball WCF Service on Codeplex for examples.
Other observations:
Because your service requires your username and passoword, each time you call it, you need to pay some very careful thought to how you're going to obtain and store the username and password.
I would urge you to specify your binding information in the app.config rather than inline in your code. Again, see the Magic8Ball WCF Service: If you create bindings in code and the endpoint changes or if they open up a new endpoint, protocol, encoding and/or binding, you'll have to recompile and redist your entire app. If you specify your bindings in config, you might just be able to get away with shipping an updated app.config.
Hope this helps.

Categories