WCF, WebAPI and OWIN IIS integrated pipeline. Skip

2020-07-16 08:36发布

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)?

2条回答
我想做一个坏孩纸
2楼-- · 2020-07-16 09:23

Big thanks to the answer above. With this piece of code, I was able to figure out how to conditionally route calls so that WCF calls are not grabbed by static content middleware.

    //app.UseMiddleware<ServeStaticFilesMiddleware>();

    app.MapWhen(c => !c.Request.Path.Value.Contains(".svc"),
            subApp =>
            {
                subApp.UseMiddleware<ServeStaticFilesMiddleware>();
            });
查看更多
走好不送
3楼-- · 2020-07-16 09:40

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 => ...
查看更多
登录 后发表回答