无法在使用";Authorize&Quot;属性装饰的SignalR集线器中标识用户上下文 [英] Unable to Identify User Context in SignalR hub decorated with "Authorize" attribute
本文介绍了无法在使用";Authorize&Quot;属性装饰的SignalR集线器中标识用户上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
服务器
MVC 5WebApi 2中的SignalR集线器, 安全性:持有者令牌客户端
使用HttpWebRequest从WebApi控制器/令牌端点检索承载令牌的C#类
我使用描述的模式here和here将承载令牌传递给我的AuthorizeAttribute子类。
当AuthorizeHubConnection方法内的代码执行调用"secureDataFormat.Untect(Token)"传递的票据时,始终为空。我已确认通信两端的令牌相同。
下面是覆盖方法:
public override bool AuthorizeHubConnection(AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
{
var dataProtectionProvider = new DpapiDataProtectionProvider();
var secureDataFormat = new TicketDataFormat(dataProtectionProvider.Create());
var token = request.QueryString.Get("Bearer");
var ticket = secureDataFormat.Unprotect(token);
if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
{
// set the authenticated user principal into environment so that it can be used in the future
request.Environment["server.User"] = new ClaimsPrincipal(ticket.Identity);
return true;
}
return false;
}
当我在没有Authorize属性的情况下运行HUB并在"OnConnected"重写中设置断点时,Context.User属性也为NULL。
如有任何帮助,我们将不胜感激。
丰富
推荐答案
这是我的解决方案,使用Azure和本地。AngularJS、Web API和SignalR request.Environment["server.User"]此代码在Azure上不起作用。 首先,我创建了我的自定义过滤类。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class QueryStringBearerAuthorizeAttribute : AuthorizeAttribute
{
public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, IRequest request)
{
var _Authorization = request.QueryString.Get("Bearer");
if (!string.IsNullOrEmpty(_Authorization))
{
var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);
if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
{
request.Environment["server.User"] = new ClaimsPrincipal(ticket.Identity);
return true;
}
}
return false;
}
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
var request=hubIncomingInvokerContext.Hub.Context.Request;
var _Authorization = request.QueryString.Get("Bearer");
if (!string.IsNullOrEmpty(_Authorization))
{
//var token = _Authorization.Replace("Bearer ", "");
var ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(_Authorization);
if (ticket != null && ticket.Identity != null && ticket.Identity.IsAuthenticated)
{
Dictionary<string, object> _DCI = new Dictionary<string, object>();
_DCI.Add("server.User", new ClaimsPrincipal(ticket.Identity));
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId);
return true;
}
}
return false;
}
}
然后,在我从SignalR建立的所有连接中,我将
connection.qs={承载: localStorageService.get(‘authorizationData’).token};
我的启动课
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true
};
var authorizer = new QueryStringBearerAuthorizeAttribute();
var module = new AuthorizeModule(authorizer, authorizer);
GlobalHost.HubPipeline.AddModule(module);
map.RunSignalR(hubConfiguration);
});
GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());
ConfigureAuth(app);
}
它非常适合我,我不确定从Header发送查询字符串的令牌是否存在安全问题。这就是我的解决方案,使用angularjs、ASP.NET web API、信号r来验证带有承载令牌的SignalR集线器。
在集线器中,您可以通过这种方式访问用户变量
public ClaimsPrincipal _User { get { return Context.Request.Environment["server.User"] as ClaimsPrincipal; } }
这篇关于无法在使用";Authorize&Quot;属性装饰的SignalR集线器中标识用户上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文