My service methods are marked with PrincipalPermissionAttribute and i have a custom IErrorHandler implementation attached to the service. When an incoming request has no permissions to execute the method System.Security.SecurityException is thrown. IErrorHandler.ProvideFault() is then triggered and i want to provide a special fault. But error parameter is not original exception, it's untyped FaultException. Moreover, error.InnerException is null despite i have the following setting in the config:
<serviceDebug includeExceptionDetailInFaults="true"/>
Why? How can i achieve the desired behavior?
According to this SecurityException is kind of "special" for WCF:
SecurityException is related to CAS
(Code Access Security), and it is a
fatal exception. Since this exception
is not related to any service model
exceptions, it cannot be handled by
IErrorHandler.
So i ended up by creating additional class which methods (called from the methods of the class implementing the service interface) are marked with PrincipalPermissionAttribute and a handler function with try/catch.
Related
I was wondering if it was possible to configure a WCF service client to use a custom type instead of FaultException when throwing faults. The custom type would inherit from FaultException, but also have some additional details about the error.
The reason I want to use a custom FaultException is so I can store a GUID from the SOAP Header which is otherwise lost.
I know I could manually catch and rethrow any faults my service client returns, but that's flimsy. I have no way of guaranteeing future developers will do the same.
I've thought about subclassing the generated service client class and putting the error handling in there, but that generates a lot of work whenever the target service changes.
So, is it possible to configure a WCF service client to throw a custom FaultException type for Faults?
You can create your own IErrorHandler implementation:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
Override ProvideFault and then do conversion from regular exceptions (including plain FaultException) to your own custom based FaultException<T>, where T is your own type that you can define to include custom properties.
After that, you have to register your implementation of IErrorHandler as service behavior, either in code or in web/app config.
I have some WCF services with predefined FaultContract attributes. When the FaultException<TDetail> exceptions are thrown, they're sending StackTrace, Source and other potentially unsave information.
Is it possible to return only:
Detail (from the generic TDetail)
FaultMessage
FaultCode
(and possibly) FaultReason
Have you tried rolling your own fault exception using IErrorHandler? Also make sure in your app config file, the IncludeExceptionDetailInFaults attribute is set to false and, this might be helpful for best pratices.
I'm currently using Castle-Windsor with the WCF Facility to inject all my WCF services. I've just started adding permission requirements using a custom IAuthorizationPolicy, which seems to work when done on a per-method basis on the service, but when the service class itself is marked up with the requirements, I get an exception thrown.
I've set things up based on the example at How To – Use Username Authentication with Transport Security in WCF from Windows Forms. I didn't set up the custom HTTP Module class as I'm using an existing Membership implementation. My IAuthorizationPolicy implementation (HttpContextPrincipalPolicy) is essentially identical.
The essential part of my Web.config is:
<serviceBehaviors\>
<behavior name="MyBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"
roleProviderName="UserProvider">
<authorizationPolicies>
<clear/>
<add policyType="Website.FormsAuth.HttpContextPrincipalPolicy,Website"/>
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
Everything seems to work fine when I put the requirements on the method. This is being done like so:
[PrincipalPermission(SecurityAction.Demand, Role = RoleNames.USER_ADMINISTRATION)]
If this is on an OperationContract method, things work as expected. However, if it is moved to the class itself (which implements the ServiceContract) I get the following exception (with most of the extra stuff pruned out):
Castle.MicroKernel.ComponentActivator.ComponentActivatorException {
Message = "ComponentActivator: could not instantiate Services.UserService"
InnerException = System.Reflection.TargetInvocationException {
Message = "Exception has been thrown by the target of an invocation."
InnerException = System.Security.SecurityException {
Message = "Request for principal permission failed."
}
}
}
I've debugged and found that the constructor on HttpContextPrincipalPolicy is being called but Evaluate() is not when the demand is attached to the class. When it is attached to the method Evaluate() is being called. So at this point I've gone as far as my newbie .NET/WCF/Castle-Windsor skills will take me.
Is there a way to tell Castle-Windsor to invoke the service constructor while honoring the IAuthorizationPolicy? Or tell WCF that Evaluate() needs to be called for the creation of the class? Or is there some other way around WCF that does the same thing? I don't want to have to mark up every single method with the exact same bit of attribute declaration.
When you mark the class itself up with a PrincipalPermissionAttribute it's effectively saying to the runtime that at the point when the class is used the permission demand must be met. So now when Castle-Windsor is trying to instantiate the class, the permission demand is being made and of course it can't be fulfilled because the security context isn't established correctly at that point.
AFAIK, PrincipalPermissionAttribute is not supported on the class level for WCF due to the nature of its runtime even though it is allowed from a pure .NET perspective. Castle-Windsor is therefore unable to create your service instance for the same reason.
I have a wcf service. The service itself (class that inherits the ServiceContract) has a constructor that sometimes throws exceptions. I want to present the user a message if the service fails. Should I use faults like I would for a service method?
A fault is generally meant to provide error information across service boundaries, and in most cases, a fault is sent as a response to a malformed or invalid request message. Given that, I would say a fault doesn't make sense here.
I agree with the above commenter that a constructor for a service class should avoid throwing exceptions. If your service is sessionful, you may want to consider a design where you do this type of initialization as the result of a specific service operation. This can be done in WCF by marking such a service operation with "IsInitiating = true" in the [OperationContract] attribute. At that point, you would be able to generate a fault and have some hope of it reaching the intended client.
I'm using WCF to implement a web service. This web service requires a 'ping' feature as a health monitor for each service. This functionality has been implemented using IDispatchMessageInspector and is configured for each endpoint of a service. This is due to a business requirement for the 'ping' to be as near the actual service code as possible. At the same time, I did not want to tie it to each service implementation's code and IDispatchMessageInspector seems to be a good fit.
The service uses a Request-Reply MEP. Each request message contains an element that specifies what processing is required. The service will then use this value to determine how to process the data in the message. The same element is used to define a request message as a 'heartbeat' check.
The 'ping' message inspector will pre-process a request message in the AfterReceiveRequest() method and if it determines the request is a 'heartbeat', it will then generate the correct response and pass that on to the BeforeSendReply() method via a correlation object returned from AfterReceiveRequest(). The request message parameter of AfterReceiveRequest(), which is by reference, is then set to null to prevent the message from being processed by the service implementation code.
The technique of setting request message to null was found in a web site or blog which I can't remember nor find the URL for. This technique works great on it's own and I can prevent service implementation code from being executed if it's a 'heartbeat' request.
Unfortunately, setting the request message to null in a message inspector will cause the WCF runtime to always throw a NullReferenceException. From the stack trace, I gather the runtime will still pass the message object (which will be null after going through 'Ping' message inspector) to the dispatcher and when the dispatcher tries to deserialise a null message object, causes the NullReferenceException.
However, my system also implements IErrorHandler to catch any unhandled exceptions in the service and log it. This means every successful 'heartbeat' request will generate a log entry for the NullReferenceException and the 'heartbeat' could be as frequent as every minute.
The Question :
What can I do to prevent logging of 'useless' NullReferenceException thrown when 'Ping' prevents service implementation code from running by setting request to null.
Many thanks in advance.
~hg
Not the most graceful solution but potential workarounds (that i've not tested), but where you detect your ping calls in the inspector code, could you not throw your own custom exception type i.e. PingRequestException, and handle this when it returns to the client? Would that avoid you hitting the WCF Runtime code, thus avoiding the logging of unhandled exceptions.
Otherwise you could try to use a base service, inherited by all of your services (the other side of the wcf runtime code) that detects and handles ping requests in the constructor before hitting the actual service code.