c# - 如果没有路由匹配,为什么 ASP.NET WebApi 会清除身份?

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

我正在尝试使用 signalr 设置一个 web api,在这个过程中我注意到了这个奇怪的地方。我似乎无法找到记录在案的原因,说明在 Web API 路由表上没有匹配项后,OwinContext 上的身份将被清空。我整理了一个简单的项目来展示这一点:

启动

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

虚拟 token 格式化程序

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

Controller

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

如果我尝试连接到集线器(在管道的末端),则 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

谁能解释为什么会这样?

附言在项目的 github 上也提出了同样的问题。 .,但我没有收到回复。(编辑:现在正在获取帮助)

最佳答案

事实证明,这是在构建 ASP.NET Web API 管道等时所做假设的结果。完整对话在 github 上上面的链接。但总结一下:

It's Just Wrong™️ not to restore the Principal.

问题已在 github 上解决,并计划在下一个版本中发布。同时,如果您发现自己遇到此问题。有一个解决方法,只需将您的 Controller 移动到子路线上。这可以防止 ASP 管道消除 Principle。

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

关于c# - 如果没有路由匹配,为什么 ASP.NET WebApi 会清除身份?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48410917/

相关文章:

c# - 如何设置 DataGridView 行/列的标题

c# - 如何在 C# 中打开 Windows 7 事务处理文件

c# - 有条件地忽略属性序列化

c# - 如何使用 LINQ 从目录中过滤文件?

.net - System.DirectoryServices.DirectoryServicesCOMException : An operations error occurred

asp.net-mvc - 将身份验证同时用于 MVC 页面和 Web API 页面?

xml - 为什么我的 ASP.Net Core Web API Controller 不返回 XML?

C# 给变量赋新值

c# - ASP.NET Core - 提供静态文件

c# - EF4 ObjectContext.EntitySet.AddObject() 级联插入