It is not very uncommon to have web sites that have web UX and services content. The UX part maybe uses WS-Federation (or some other redirect based mechanism). That means whenever an authorization error occurs (401 status code), this is picked by the corresponding redirect module and turned into a redirect (302) to the login page. All is good.
But in services, when you emit a 401, you typically want that status code to travel back to the client agent, so it can do error handling. These two approaches conflict.
If you think (like me) that you should separate UX and services into separate apps, you don’t need to read on. Just do it ;)
If you need to mix both mechanisms in a single app – here’s how I solved it for a project.
I sub classed the redirect module – this was in my case the WIF WS-Federation HTTP module and modified the OnAuthorizationFailed method. In there I check for a special HttpContext item, and if that is present, I suppress the redirect. Otherwise everything works as normal:
class ServiceAwareWSFederationAuthenticationModule : WSFederationAuthenticationModule
protected override void OnAuthorizationFailed(AuthorizationFailedEventArgs e)
var isService = HttpContext.Current.Items[AdvertiseWcfInHttpPipelineBehavior.DefaultLabel];
if (isService != null)
e.RedirectToIdentityProvider = false;
Now the question is, how do you smuggle that value into the HttpContext. If it is a MVC based web service, that’s easy of course. In the case of WCF, one approach that worked for me was to set it in a service behavior (dispatch message inspector to be exact):
public void BeforeSendReply(
ref Message reply, object correlationState)
if (HttpContext.Current != null)
HttpContext.Current.Items[DefaultLabel] = true;