Simon Fox Simon Fox - 27 days ago 24
ASP.NET (C#) Question

WCF, WebAPI and OWIN IIS integrated pipeline. Skip OWIN based on route

Situation

I have a Silverlight application that uses a WCF backend. Going forward we have moved to JS clients with WebAPI.

I have a couple of WebAPI controllers that I would like to use from the Silverlight client and so have them loaded within the ASP.Net application that hosts the WCF services.

This works fine from a "all services are available" point of view, however Authorization is being invoked multiple times for WCF calls; from OWIN and through WCF

ServiceAuthorizationManager


On the WCF side, my ServiceAuthorizationManager implementation validates the token in the AuthHeader and then transforms that token (in the System.IdentityModel Claims Transformation sense). On the WebAPI side I'm using Thinktecture.IdentityModel which provides OWIN Middleware to do token validation and claims transformation .

Problem is, the OWIN middleware gets invoked for all requests (including the WCF requests). So in the case of a WCF request I get validation and transformation executed twice. I can't just remove the ServiceAuthorizationManager and let the middleware handle it, because WCF knows nothing of OWIN and the final step of the ServiceAuthorizationManager is to set the operation context principal (different to ClaimsPrincipal.Current).

Question

Has anyone had a problem like this before with WCF and WebAPI sitting side by side? Would the best approach be to somehow drop out of the OWIN pipeline very early on for WCF calls and if so how can that be done, through an OMC? Or can I somehow use the IAppBuilder.Map approach to only register the token validation and transformation components for API routes (in this case anything starting /api)?

Answer

I've managed to get this to work via a Branched Pipeline.

app.MapWhen(c => c.Request.Path.Value.Contains("/api"),
                    subApp =>
                    {
                        subApp.UseJsonWebToken(
                            issuer: clientDetails.Issuer,
                            audience: clientDetails.Audience,
                            signingKey: clientDetails.SigningKey);

                        subApp.UseClaimsTransformation(transformer.Transform);

                        var webApiConfig = WebApiConfig.Configure();
                        webApiConfig.DependencyResolver = StructureMapConfig.HttpDependencyResolver();
                        subApp.UseWebApi(webApiConfig);
                    });

Only thing I'm wondering is why IAppBuilder.MapWhen as above works, but when I use IAppBuilder.Map it doesn't seem to work...

app.Map("/api",
        subApp => ...
Comments