好的,所以这个肯定会把我推向悬崖的边缘......与SignalR
的V1合作相对容易,我现在肯定在挣扎。
问题:"抓住"来自最近通过身份验证的用户Claims
并在Hub
环境:
WebAPI使用Basic Auth
对SSL
进行身份验证。验证的逻辑在一个属性内并且工作正常并且已经持续数月,它还在AuthenticateAsync
在我的API Controller
中,我抓住了声明:
var idenityInstance = new IdentityInstance(this.User as ClaimsPrincipal);
我周末花了很多时间尝试使用Groups / SSL和Authentication来合并SignalR的V2。
我一般认为ClaimsPrincipal会传递或传递给#34; Context"。
public void Configuration(IAppBuilder app)
{
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
自定义授权属性(从文档中获取)
protected override bool UserAuthorized(System.Security.Principal.IPrincipal user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
var principal = user as ClaimsPrincipal;
if (principal != null)
{
Claim authenticated = principal.FindFirst(ClaimTypes.Authentication);
if (authenticated != null && authenticated.Value == "true")
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
好的,最后一个片段,The Hub(剥离后的)
public async Task Hello()
{
//Temp line for testing under local SSL/Self signed
ServicePointManager.ServerCertificateValidationCallback
+= (sender, cert, chain, sslPolicyErrors) => true;
var hubConnection = new HubConnection("https://localhost:44357");
IHubProxy chatHubProxy = hubConnection.CreateHubProxy("printerHub");
hubConnection.Start().Wait();
var c = Context;
await hubContext.Clients.All.hello("Hello");
}
问题是当我通过Hub Method Hello();
Context
进行调试始终是null
时,由于自定义authenticate
我希望我在这里错过了一些愚蠢的事情,因为它肯定非常令人沮丧。
答案 0 :(得分:1)
好吧,这比首次预期的要复杂一些,现在解决方案可能不适合“某些”环境,但在这种情况下,解决了问题。
我们始终牢记我们正在处理两个Contexts
...
要重新上限,我WebAPI
basic auth
超过SSL
- 效果非常好,现在的想法是提供一种方法来锁定{{1}并且仅允许访问经过身份验证的用户且超出Hubs
的范围。由于basic auth
和WebAPI
在两个进程中运行,SignalR
的访问权限可以在Hubs
管道之外。
要演示的一些代码:
中心:
WebAPI
SignalR自定义身份验证属性
[HubAuthorizationAttribute]
[HubName("printerHub")]
public class PrinterHub : Hub
{
private static IHubContext hubContext =
GlobalHost.ConnectionManager.GetHubContext<PrinterHub>();
private IdentityInstance _userInstanceContext;
private User _user;
public override Task OnConnected()
{
//Custom logic to return a User object
_userInstanceContext = new IdentityInstance(this.Context.User as ClaimsPrincipal);
_user = _userInstanceContext.Create();
return base.OnConnected();
}
public override Task OnDisconnected(bool stopping)
{
return base.OnDisconnected(stopping);
}
public async Task JoinPrinterNotifications()
{
await hubContext.Groups.Add(Context.ConnectionId, _user.ClientName + ":Printers");
}
public async Task PrintQueues(IEnumerable<QueuedPrintItem> items)
{
await hubContext.Clients.Group(_user.ClientName + ":Printers").notify(items);
}