My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.
Related
Let's assume we have a RESTful web service that will calculate UK Royal Mail postage charges.
There would be a number of essential input parameters:
weight of item (grams, int),
length of item (cm, int),
width of item (cm, int),
category of item (letter/parcel, string/enum),
service required (first class/second class/special delivery/etc, string/enum),
destination (domestic/international/maybe further specify the latter, string/enum)
Such an application would be easy to create as a WebAPI. It could be called via a URL such as ...
http://myserver.com/api/mailcharges?weight=150&length=15&width=10&category=letter&service=first&destination=domestic
The web service would then do a simple lookup on its internal tables and return the postage in its response payload.
The beauty of this is that it could then be utilised by a variety of applications within an organisation (or even outside it!). However, this requires that each application that calls the web service needs to be able to populate these parameters; the integers are OK, they are just that - numbers. But the strings or enums are more difficult. The logic for entering and validating these needs to be replicated in every client application. Wouldn't it be nicer if the web service could prompt the user for any which are not passed in or passed as nulls or invalid values. In fact wouldn't it be nicer still if the web service had a user interface which allowed a user to enter any or all of the parameters.
What I am looking for is a cross between a web site and a web service. A web application which can be called via a simple RESTful http request, which pops up a user dialogue, accepts user input, and when the user clicks on a suitable button, does its calculation and returns its answers as a JSON/XML response.
Does anyone have any ideas on how to implement such an architecture? I have tried calling MVC actions/views from within a web api controller but the response is the html for the MVC view, and is returned to the api controller directly rather than being rendered and POSTing back its user input.
I hope I am just being thick, and that the answer is obvious, but all my experiments have so far failed, and any suggestions, no matter how far fetched or outrageous, would be very welcome.
I realize that this is a fairly trivial example, but the same argument goes for much more complicated web services where the replication of user input forms, input validation, complex processing logic etc. across multiple client applications would be far more of an issue than with this example.
if the web service could prompt the user is essentially missing the point of a service. It is no longer a webservice, but a webpage.
In order for internal/external applications/websites to utilize your service, they essentially need to know three things:
where to ask - this is your http://myserver.com/api/mailcharges
what are the arguments - that is weight, length…
what are accepted argument values
While 1. and 2. are usually mere API documentation you seem to have a problem with p. 3 - you want the user to be somehow prompted to choose among possible values and not guess. But you also want the user application not to be responsible for maintaining/validating the list of possible values.
Guess what? You simply need another API. :) An API to describe your arguments.
Let's concentrate on category field. Your API could be extended with a new URL: http://myserver.com/api/getCategories which essentially returns a list of available (currently understood by API) possible category values. This can be JSON, or comma separated string or whatever reliable. Now your end-user GUI-enabled application calls the API, asks for categories, and creates UI accordingly - populating ComboBox or whatever with obtained values. The same is done for other fields. You can. i.e. obtain acceptable ranges of weight or length.
The important thing you mention in your question is validation: logic for entering and validating these needs to be replicated in every client application. This is somehow true, as it essentially depends on the technology used in the end-user application. On the other hand it is very important, that the API performs validation itself! You can never know who is going to use your API. And it is always better to check twice then never.
I have the following situation (outline):
Authorization Webservice
This service gets called and verifies (by executing the given business logic) whether a user is valid or not.
Custom Business Webservice
This is some webservice created for a business app, that internally calls the "Authorization Webservice" in order to verify the account which called the business webservice.
I realized this logic by making use of WCF service authorization in my "Custom Business Webservice". Basically I configured
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="MyCompany.Authorization.WCF.AuthorizationPolicy, MyCompany.AuthorizationDll"/>
</authorizationPolicies>
</serviceAuthorization>
The AuthorizationPolicy internally invokes the "Authorization Webservice".
The Problem
The problem is that I need to impersonate the caller of my "Custom Business Webservice". The client identity is the correct one, however the WindowsIdentity is that of the application pool user.
Note, impersonation works within the service itself if I use [OperationBehavior(Impersonation = ImpersonationOption.Required)] but it does not within the AuthorizationPolicy's Evaluate(...) method.
(I use Transport level security using windows authentication credentials, obviously)
Anyone has any hints on how I can impersonate the caller prior to entering the IAuthorizationPolicy.Evaluate(...) method??
It always again feels a bit strange, answering to my own questions, but for the sake of sharing what I got with others I'm going to post the "solution" here.
I'll try to make it short:
Impersonating in the IAuthorizationPolicy.Evaluate(...) is not possible. (S4U2Self may work, didn't test that since I didn't have that option)
As I already mentioned, impersonating the caller within the webservice operation worked by placing the [OperationBehavior(Impersonation = ImpersonationOption.Required)]. So calling my custom webservice for retrieving the principal as the first statement in my service operation would always work. I didn't like that approach however.
As an alternative I tried to find the latest possible point in the call chain of a WCF service operation where the impersonation finally worked. This is where I found the OperationInvoker.
The following diagram illustrates the sequence of dispatchings that are done before the call arrives at the actual operation (taken from here):
Parameter Inspection was too early, impersonation didn't yet work, but it luckily worked in the Operation Invoker. So by writing a custom operation invoker and wrapping everything into a custom operation behavior attribute I was able to elegantly solve the problem.
More info on an according blog post I wrote.
The current situation is as follows:
We have an production .net 3.5 WCF service, used by several applications throughout the organization, over wsHttpBinding or netTcpBinding. User authentication is being done on the Transport level, using Windows integrated security. This service has a method Foo(string parameter), which can only be called by members of given AD groups. The string parameter is obligatory.
A new client application has come into play (.net 3.5, C# console app), which eliminates the necessity of the string parameter. However, only calls from this particular application should be allowed to omit the string parameter. The identity of the caller of the client application should still be known by the server because the AD group limitation still applies (ruling out impersonation on the client side).
I found a way to pass on the "evidence" of the calling (strong-named) assembly in the message headers, but this method is clearly not secure because the "evidence" can easily be spoofed.
Also, CAS (code access security) seems like a possible solution, but I can't seem to figure out how to make use of CAS in this particular scenario.
Does anyone have a suggestion on how to solve this issue?
Edit: I found another thread on this subject; apparently the conclusion there is that it is simply impossible to implement in a secure fashion.
sounds to me like you need to pull the security out into a seperate service ... go down a more federated route this way you can implement a handshake form of encryption using public and private keys to generate a secure session token in both situations.
this way you cna still get both windows a=uthentication and a custom solution in play whilst retaining your attributes on methods for security (I am assuming that you are implementing it this way.)
sounds like a fair bit of work though - I had to do this from scratch and ran into some cross domain / delegation issues. But I am sure the idea is good.
howver you will end up with a nice solid claims based secuirty model
You could get the callers Address:
RemoteEndpointMessageProperty clientAddress =
OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name]
as RemoteEndpointMessageProperty;
string address = clientAddress.Address;
I'm currently working on a WCF service that reaches out to another service to submit information in a few of its operations. The proxy for the second service is generated through the strongly typed ProxyFactory<T> class. I haven't experienced any issues but have heard I should do something like the following when making the call:
using (new OperationContextScope((IContextChannel)_service))
_service.Send(message);
So my question is: when is creating this new OperationContextScope appropriate, and why?
Thanks!
If you are using callbacks or if you want to modify the message or headers then you need to use OperationContextScope. Your service might need to modify outgoing headers while calling that another service.
When you establish OperationContextScope then you can:
Access and modify incoming and outgoing message headers and other properties.
Access the runtime, including dispatchers, the host, channel, and extensions.
Access other types of contexts, such as security, instance, and request contexts.
Access the channel associated with the OperationContext object or (if the channel implements System.ServiceModel.Channels.ISession) the associated channel's session identifier.
The other service which you call, is it a session-based service? Probably you need to look at its sample client code or documentation if available.
This question is about “informational messages” and having them flow from a “back end” to a “front end” in a consistent manner. The quick question is “how do you do it”?
Background:
Web application using WCF to call back end services.
In the back end service a “message” may occur. Now, the reason for this “message” may be a number of reasons, but for this discussion let’s assume that a piece of data was looked at and it was determined that the caller should be given back some information regarding it.
This “informational” message may occur during a save and also may occur during retrieval of information. Again, the message is not what is important here, but the fact that there is some informational messages to give back under a number of different scenarios.
From a team perspective we all want to return these “messages” in a standard way all of the time. Now, in the past this “standard way” has been done different ways by different people.
Here are some possibilities:
1) Every operation has a “ref” parameter at the end that contains these messages
2) Every method returns these messages… however, this only kind of works for “Save” methods as one would think that “Retrieve” methods should return actual data and not messages
3) Some approach using the call context so as to not "pollute" all message signatures with something; however, with WCF in the picture this complicates things. That is, going back to the messages go on a header?
Question:
Back to my question then… how are others returning “messages” such as what was described above back through tiers of an application, over WCF and back to the caller?
I think you basically have two proper ways of doing this:
add a InfoMessage : string field to all your DataContracts, which can hold an informational message (or not) back from the server
If you don't want to put that into the DataContracts, then create a header which you populate on the server before the message goes back to the client, and on the client, you can inspect that header and retrieve it if present
In order to automagically add headers to WCF messages, typically the mechanism of MessageInspectors is used - little chunks of code that can be configured or added by means of an attribute on your operation contract, that will add the header on the one end, and inspect the incoming message for that header (and extract it, if present) on the other end.
There are a number of pretty good blog post out there showing you how to create a message inspector:
Richard Hallgren's WCF postings
Writing a WCF message inspector
Automatic Culture Flowing with WCF by using Custom Behaviour
Those mostly go from client to server, e.g. the client sends along a header with some "meta-information" for the service - but it works just fine the other way around, too.
Check out the two relevant interfaces to implement:
IClientMessageInspector on the client side, which has a BeforeSendRequest and AfterReceiveReply message to implement
IDispatchMessageInspector on the server side, which has a AfterReceiveRequest and BeforeSendReply method to implement