我正在尝试使用 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/