简体   繁体   English

中间件运行后,带有WebApi控制器的Owin中间件不会移至webapi路由

[英]Owin Middleware with WebApi controllers not moving to webapi routes after middleware runs

I'm using WebApi on top of Owin, and I'm getting 404 on routes that are mapped with http attribute routes where middleware runs first, although the middleware is running correctly. 我在Owin上使用WebApi,并且在中间件先运行的http属性路由映射的路由上得到404,尽管中间件运行正确。 I would have thought the call to UseWebApi happening last would sign up those routes to run as the last middleware in the pipeline. 我本以为对UseWebApi的调用将在最后发生,从而将那些路由注册为管道中的最后一个中间件。 What am I missing? 我想念什么?

  • Calls to "/token" work. 调用“ / token”作品。
  • Calls with missing or incorrect X-Auth-Token to /user/domainid/{id} get 403'd as expected. 与/ user / domainid / {id}的X-Auth-Token丢失或错误的呼叫按预期得到403。
  • Calls with correct X-Auth-Token to /user/domainid/{id} get 404'd (This is what I can't figure out.) 使用正确的X-Auth-Token到/ user / domainid / {id}的呼叫得到404(这是我不知道的。)

Here is my startup: 这是我的创业公司:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();

    var container = new Container();
    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
    container.RegisterSingleton<IADSearchService>(new ADSearchService());
    container.RegisterWebApiControllers(config);
    container.Verify();

    config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

    app.Use(async (context, next) =>
    {
        using (AsyncScopedLifestyle.BeginScope(container))
        {
            await next();
        }
    });

    app.MapWhen(
        context => !context.Request.Uri.PathAndQuery.StartsWith("/token"),
        builder => builder.UseAuthorizationMiddleware());

    app.UseWebApi(config);
}

Authorization middleware: 授权中间件:

class AuthorizationMiddleware : OwinMiddleware
{
    public AuthorizationMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        var auth = context.Request.Headers.Get("X-Auth-Token");
        if (auth == null || auth != "12345")
        {
            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            return;
        }
        // Edit: I've discovered that Next is null here when
        // calling /user/domainid/{id} with the right X-Auth-Token.
        await Next.Invoke(context);
    }
}

WebApi Controller that doesn't run: 无法运行的WebApi控制器:

[RoutePrefix("user")]
public class UserController : ApiController
{
    private readonly IADSearchService adSearch;

    public UserController(IADSearchService iADSearch)
    {
        this.adSearch = iADSearch;
    }

    [Route("domainid/{id}")]
    [HttpGet]
    public IHttpActionResult GetUserByDomainID(string id)
    {
        var user = adSearch.GetUserBySAM(id).ToDomainUser();
        if (user == null)
        {
            return NotFound();
        }

        return Json(user);
    }
}

But this controller does run: 但是此控制器确实可以运行:

[Route("token")]
public class TokenController : ApiController
{
    [HttpGet]
    public IHttpActionResult Authenticate()
    {
        return Ok("This is a token!");
    }
}

Edit: I've discovered that Next in the AuthorizationMiddleware implementation is null during correct calls to /user/domainid/{id}. 编辑:我发现在正确调用/ user / domainid / {id}期间,AuthorizationMiddleware实现中的Next为空。

How can I ensure the webapi routes get registered as Next in preceding middleware layers? 如何确保在前面的中间件层中将webapi路由注册为Next?

Edit2: I've managed to get it working by adding another call to UseWebApi within the app.MapWhen. Edit2:通过在app.MapWhen中添加对UseWebApi的另一个调用,我设法使其正常工作。 I feel like this shouldn't be necessary and am still wondering what the correct solution is here. 我觉得这不是必须的,并且仍然想知道这里的正确解决方案是什么。 I'd expect to be able make conditional branches on the IAppBuilder without duplicating calls to UseWebApi, maybe not though. 我希望能够在IAppBuilder上建立条件分支,而不会重复调用UseWebApi,也许不是。

app.MapWhen(
    ctx => !ctx.Request.Uri.PathAndQuery.StartsWith("/token"),
    builder =>
    {
        builder.UseAuthorizationMiddleware();
        builder.UseWebApi(config);
     });
app.UseWebApi(config);

MapWhen creates a branch of the pipeline. MapWhen创建管道的分支。 If you want to stay in the same pipeline, UseWhen seems to work. 如果要保留在同一管道中, UseWhen似乎可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM