Why WCF SoapFault responses are encrypted in some situations? - wcf

I am creating a WCF webservice whose requests/responses are supposed to be signed only.
For this, on ServiceContract attribute I have set
ProtectionLevel = ProtectionLevel.Sign
That works ok.
Due to requirements some SoapFaults are supposed to be thrown from service; two types of SoapFaults:
related to application
related to WS-Addressing (e.g. MessageID is missing)
For this I am using the normal of approach of dealing with SoafFaults: create an IErrorHandler in which a Message instance is created with MessageFault.CreateFault.
Almost all the returned SoapFaults are not encrypted (which is ok for me),
my question is why the ones with action="http://www.w3.org/2005/08/addressing/fault" or "http://www.w3.org/2005/08/addressing/soap/fault" are encrypted?

Check out http://msdn.microsoft.com/en-us/library/aa347791.aspx and http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx.
It states that
If you select a binding that enables security and you do not set the
ProtectionLevel property anywhere on the contract, all application
data will be encrypted and signed.
I guess that the build in types by default use this behaviour. You can verify this by looking at which exception is actually thrown.

Related

SecurityContext.Current not working, nullexception

im using a WCF service with the users and roles being kept in the database. In my service im trying to identify whose calling the service. So i type in my WCF service
string user = ServiceSecurityContext.Current.PrimaryIdentity.Name;
but i get i nullexception object not sent to an reference, ive tried googleing it all day but cant seem to find whats wrong. Any suggestions ?
"What's wrong" is that ServiceSecurityContext.Current is returning null rather than an instance of ServiceSecurityContext.
One scenario where this occurs is if the binding is configured to use Message security with MessageCredentialType set to None.
However, I'm not aware of any comprehensive documentation listing every scenario where ServiceSecurityContext.Current can be null: as the security context is established in the channel stack it is something which depends on the specific binding configuration and security providers in use. It could also, I imagine, be affected by custom Behaviors which fiddle with message properties.
Having said that, unless you have custom code inserted into the channel stack, it is probably a safe assumption that this will only occur in cases where the binding does not require any client authentication. You should check first of all that you are using a binding configuration which will auhenticate the client and provide the kind of user name IIdentity you are expecting.

Validation exceptions from a WCF service

I'd like some help with this one.
I want to return some kind of validation exception from my WCF service if the given entity data doesn't pass the business logic, but I'm not sure the best way to return muliple things from a WCF Service (for example a validation error and a list of entities).
This one might be really simple, but even so, I'd appreciate a little help.
I would suggest you take a look at the Enterprise Library Validation Block:
http://msdn.microsoft.com/en-us/library/ff648951.aspx
http://msdn.microsoft.com/en-us/library/ff648939.aspx (note this is for EntLib 3.1, which is a bit dated, but even in EntLib 5, WCF integration works similarly)
I've used this approach a number of times for WCF validation and it works out quite well. You'll end up decorating your data contracts with validation attributes that are part of EntLib. This defines what your validation rules are. Then you configure your service to use Enterprise Library's WCF extensibility. This is an endpoint behavior, so essentially this intercepts any incoming messages for your serivce, checks that all the defined validation attributes pass and then sends the message on to your service option. If the rules specified by your validation attributes don't pass then the endpoint behavior returns a fault message that contains the details about all validation failures. So, if one attribute didn't pass, there would be one message. If three attributes didn't pass, you'd have three messages and so on. Each validation failure message references what property didn't pass validation. The nice thing about the EntLib validation WCF integration is that the fault messages used for validation failures are strongly types and available in your service's WSDL. This means that your clients can easily consume these faults and act upon them appropriately.
If you feel like Enterprise Library is a little too heavy for your needs then you could certainly roll your own validation. You'd probably want the data contracts returned by your service operations to include something like a List that cotains validation messages.

Approach to pass validation result, on failure, from WCF service (with EF4 data processing) to MVC3 client

I implement a ASP.NET MVC3 application, where data is accessed through WCF services.
The WCF service uses EF4.1 for data access with DBContext and POCO classes for entities.
I can annotate the properties with data validations attributes on the server side, and also I can implement custom validation by defining either custom validation attributes (derived from ValidationAttribute), or by implementing IValidatableObject ).
But I have a problem: if validation fails, what is the best approaoch to pass validation error info from WCF to client, and then use it in MCV3 client?
As I understand with WCF, every data exchanged between client and WC service should be part of the data contract, and should not use exceptions as ways of passing meaningful information between server and client (like throwing a ValidationException with extra properties set for Validation failure info).
Also in WCF who uses EF I call dbContext.SaveData(), but if data is not valid, it throws exception, which I don't want.
So:
how can I call validation explicitly in EF and make sure either the object is valid and I can call SaveData(), or the object is invalid and I can collect somehow validation failure information to pass to client.
Haw can I pass this validation failure information back to client, as part of data contract, and not an an exception.
Thanks
You can use two approaches:
Use standard response data contract for success and fault contract with FaultException<YourFaultContract> for validation failure. Typed fault exceptions are way to define "expected" exceptions - it is just another data contract passed in SOAP Fault describing some failure.
Create response data contract which contains something like result code, response data, failure message etc. and use this data contract for both success and failure. I don't like this approach but it is easier to use in some ESB where faults are processed in special way.

WCF using Enterprise Library Validation Application Block - how to get hold of invalid messages?

I've got some WCF services (hosted in IIS 6) which use the Enterprise Library (4.0) Validation Application Block. If a client submits a message which fails validation (i.e. gets thrown back in a ValidationFault exception), I'd quite like to be able to log the message XML somewhere (using code, no IIS logs). All the validation happens before the service implementation code kicks in.
I'm sure it's possible to set up some class to get run before the service implementation (presumably this is how the Validation Application Block works), but I can't remember how, or work out exactly what to search for.
Is it possible to create a class and associated configuration that will give me access to either the whole SOAP request message, or at least the message body?
Take a look at using the Policy Injection Application Block...
I'm currently developing an application in which I intercept (using PIAB) all requests incoming to the server and based on the type of request I apply different validation behavior using the VAB.
Here's an article about integrating PIAB with WCF:
http://msdn.microsoft.com/en-us/magazine/cc136759.aspx
You can create different inteception mechanisms such as attributes applied to exposed operations.
You could log the whole WCF Message:
http://msdn.microsoft.com/en-us/library/ms730064.aspx
Or you could combine it with Enterprise Library Logging Application Block.
I found a blog post which seems to do what I want - you create a class that implements IDispatchMessageInspector. In the AfterReceiveRequest method, you have access to the whole incoming message, so can log away. This occurs after authentication, so you also have access to the user name - handy for logging. You can create supporting classes that let you assign this behaviour to services via attributes and/or configuration.
IDispatchMessageInspector also gives you a BeforeSendReply method, so you could log (or alter) your response message.
Now when customers attempt to literally hand-craft SOAP request messages (not even using some kind of DOM object) to our services, we have easy-to-access proof that they are sending rubbish!

Problem with WCF client calling one-way operation

I have run into a problem when calling web service on a SAP PI bus from my WCF client.
The operation is defined as one-way, and the method on my proxy operation contract is decorated accordingly when the service reference is added.
However, the service client gets an exception when calling the according operation:
The one-way operation returned a non-null message with Action=''
Using SoapUI, the method on the bus can be called successfully, and it returns a SOAP envelope with an empty body. The bus people told me, this is according to the SOAP specs:
(SOAP specs, chapter 4.7.9, One-way operations):
There are differing interpretations of how HTTP is to be used when performing one-way operations.
R2714 For one-way operations, an INSTANCE MUST NOT return a HTTP response that contains an envelope. Specifically, the HTTP response entity-body must be empty.
R2750 A CONSUMER MUST ignore an envelope carried in a HTTP response message in a one-way operation.
R2727 For one-way operations, a CONSUMER MUST NOT interpret a successful HTTP response status code (i.e., 2xx) to mean the message is valid or that the receiver would process it.
So it seems, my WCF client doesn't comply with R2750.
I have found out that when I force the operation contract on the proxy to be IsOneWay = false, everything works.
Is there anything wrong with the way WCF handles one way operations or do I do something wrong (more likely)?
Is there anything else I should do, it just doesn't seem right to override the generated WCF proxy client.
Thanks for any suggestions.
It looks like SAP PI incorrectly sends an empty SOAP envelope and .NET incorrectly interprets that envelope.
Some options from this thread:
alter the generated proxy and remove OneWay=true (or add OneWay=false) to the method definition
catch the Protocol Violation in an exception handler and ignore it
use a 2.0 style webreference to call the service
apply SAP patch Note 1459995 - Soap Sender Adapter HTTP 202 and add &responsecode202=true to the url
The first and last options both worked for me. Further discussion on this sap.com thread.
I would take a look at this article as well by Gerben van Loon here. One way operation might not really be one way according to the standards.
Check this SAP thread out for the complete discussion:
http://scn.sap.com/thread/1627368
#Brian Low has answered this question correctly and very thoroughly (is should get marked as the answer).
I would also like to add that this is a known error in which the SOAP Adapter does not comply with the aforementioned WS-I Basic Profile 1.1 (R2750) and WCF does not comply with (R2750). The result... Hours of wasted time and teeth gnashing....
I believe that this particular problem can be fixed by adding the following attribute declaration to the operation in the client porxy:
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped)]
Without seeing what the signature of the method looks like, my best guess is that your method defined to return something other than "void". Since the operation is one-way, the method can only be defined using "void" (has no return). Anything else, and the operation is NOT one-way.