如果没有路由匹配,为什么ASP.NET WebApi会清除Identity?

时间:2018-01-23 21:13:27

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

我正在尝试使用signalr设置web api,在此过程中我注意到了这种奇怪的现象。在web api路由表上没有匹配之后,我似乎无法找到为什么OwinContext上的Identity将被清空的原因。我整理了一个简单的项目来展示这一点:

启动

public void Configuration(IAppBuilder appBuilder)
{
    var config = new HttpConfiguration();
    config.Filters.Clear();
    config.SuppressDefaultHostAuthentication();
    appBuilder.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        AccessTokenFormat = new TokenFormatter(),
        AuthenticationType = "DummyAuth",
        Provider = new OAuthBearerAuthenticationProvider
        {
            OnValidateIdentity = async (ctx) => ctx.Validated(ctx.Ticket),
            OnRequestToken = async (ctx) => ctx.Token = "111"
        }
    });
    appBuilder.Use<DebugMiddleware>("New Request", (Action<IOwinContext>)((IOwinContext ctx) => Console.WriteLine("End Request")));
    appBuilder.UseCors(CorsOptions.AllowAll);
    appBuilder.Use<DebugMiddleware>("Before WebApi");
    config.MapHttpAttributeRoutes();
    appBuilder.UseWebApi(config);
    appBuilder.Use<DebugMiddleware>("After WebApi");
    appBuilder.RunSignalR();
    appBuilder.Use<DebugMiddleware>("After SignalR");
    config.EnsureInitialized();
}

虚拟令牌格式化程序

public class TokenFormatter : ISecureDataFormat<AuthenticationTicket>
{
    public string Protect(AuthenticationTicket data)
    {
        return "111";
    }
    public AuthenticationTicket Unprotect(string protectedText)
    {
        var identity = new ClaimsIdentity("DummyAuth");
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Bob"));
        identity.AddClaim(new Claim(ClaimTypes.Name, "Bob"));
        var ticket = new AuthenticationTicket(identity, null);
        return ticket;
    }
}

控制器

[Authorize]
public class TestController : ApiController
{
    [Route("Value")]
    [HttpGet]
    public string GetValue()
    {
        return "Hello World!";
    }
}

集线器

public class TestHub : Hub
{
    public override Task OnConnected()
    {
        Console.WriteLine($"Hub.OnConnected Username: {new OwinContext(Context.Request.Environment).Authentication?.User?.Identity?.Name}");
        return base.OnConnected();
    }
    public override Task OnDisconnected(bool stopCalled)
    {
        Console.WriteLine($"Hub.OnDisconnected Username: {new OwinContext(Context.Request.Environment).Authentication?.User?.Identity?.Name}");
        return base.OnDisconnected(stopCalled);
    }
}

如果我尝试连接到Hub(在管道的末尾),则不再对OwinContext进行身份验证。 每个DebugMiddleware的输出显示:

输出

> Start Request
Authenticated?: True
User: Bob
Before WebApi
Authenticated?: True
User: Bob
After WebApi
**Authenticated?: False** <- Why the change here?
**User:**
End Request

有人可以解释为什么会这样吗?

P.S。同样的问题在项目github上被问到,但我没有回复。编辑:现在获得帮助)< / p>

1 个答案:

答案 0 :(得分:0)

这结果是在构建ASP.NET Web API管道时做出的假设的结果。完整对话位于上方的github链接中。但总结一下:

  

Just Wrong™️不能恢复校长。

问题已在github上解决,并计划在下一个版本中使用。同时,如果你发现自己有这个问题。有一种解决方法,只需将控制器移动到子路径上即可。这可以防止ASP管道消除原则。

appBuilder.Map("api" app => {
   app.UseWebApi(config);
   // Principal no longer available the UseWebApi middleware 
};
appBuilder.RunSignalR(); // <- still has access to principal