Web Apps vs Web Services: 302s and 401s are not always good Friends

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)
    {
       
base
.OnAuthorizationFailed(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;
    }
}

HTH

This entry was posted in IdentityModel. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s