具有WebApi控制器的Owin中间件在中间件​​运行后不会移动到webapi路由

时间:2017-09-26 16:06:45

标签: c# asp.net-web-api owin

我在Owin上使用WebApi,虽然中间件正常运行,但我在使用中间件首先运行的http属性路由映射的路由上获得404。我原本以为最后发生的UseWebApi调用会将这些路由注册为管道中的最后一个中间件。我错过了什么?

  • 致电" / token"工作
  • 缺少或不正确的X-Auth-Token对/ user / domainid / {id}的呼叫按预期获得403' d。
  • 使用正确的X-Auth-Token调用/ user / domainid / {id}获取404' d(这是我无法弄清楚的。)

这是我的创业公司:

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);
}

授权中间件:

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控制器:

[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);
    }
}

但是这个控制器确实运行了:

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

编辑:我发现在正确调用/ user / domainid / {id}期间,AuthorizationMiddleware实现中的Next为null。

如何确保webapi路由在前面的中间件层中注册为Next?

Edit2:我已经成功通过在app.Map中添加对UseWebApi的另一个调用来实现它。我觉得这不应该是必要的,我仍然想知道正确解决方案在这里。我期望能够在IAppBuilder上创建条件分支,而不会重复调用UseWebApi,但可能不会。

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

1 个答案:

答案 0 :(得分:0)

MapWhen创建管道的分支。如果您希望停留在同一管道中,UseWhen似乎可以正常工作。