i have some services on ServiceStack and use SignalR in this project.
And now, i would like to secure hub connection (access only for authenticated users), but i use ServiceStack framework authentication.. (not asp.net authentication) and ServiceStack's sessions (write AuthUserId ih this session and authentication flag).
So, when user trying connect to the hub -- hub must to check authentication...
(yes, i can request Cookies from Hub (method OnConnected, for example), but SignalR check authentication in Authorize Attribute - and i must do it in this class (not in hub)
(http://www.asp.net/signalr/overview/signalr-20/security/hub-authorization)
So, i create class
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class AuthorizeMyAttribute : AuthorizeAttribute
{
protected override bool UserAuthorized(System.Security.Principal.IPrincipal user)
{
//... how can i request Cookies? / or may be can access for ServiceStack session...
// and return true or false
}
}
What can i do for it? Thanks!
SignalR provides the Authorize attribute to specify which users or roles have access to a hub or method. This attribute is located in the Microsoft.AspNet.SignalR namespace. You apply the Authorize attribute to either a hub or particular methods in a hub.
In a hub, authentication data can be accessed from the HubConnectionContext.User property. Authentication allows the hub to call methods on all connections associated with a user. For more information, see Manage users and groups in SignalR.
SignalR can be used with ASP.NET Core authentication to associate a user with each connection. In a hub, authentication data can be accessed from the HubConnectionContext.User property. Authentication allows the hub to call methods on all connections associated with a user. For more information, see Manage users and groups in SignalR.
When this is applied to any method or a hub, the specified authorization requirement is applied to all the methods in the hub. If the Authorize attribute is not applied, a connected client can access any public method on the hub. The following code snippet helps to apply the attribute:
AuthorizeAttribute has two more virtual methods:
AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
http://msdn.microsoft.com/en-us/library/microsoft.aspnet.signalr.authorizeattribute(v=vs.118).aspx
The default implementations of both methods call UserAuthorized
with the request's IPrincipal
.
AuthorizeHubConnection
is passed an IRequest
directly.
In AuthorizeHubMethodInvocation
, you can access the IRequest
object from the IHubIncomingInvokerContext
like so: hubIncomingInvokerContext.Hub.Context.Request
.
I still struggled with this for some time trying to get the ServiceStack.Web.IRequest from the SignalR.IRequest so I could use ServiceStack's functions to request the session to see if the user had been auth'd. In the end I gave up and got the cookies from SignalR. I hope the following code snippet helps someone else nagivate this.
public class AuthorizeAttributeEx : AuthorizeAttribute
{
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
return IsUserAuthorized(request);
}
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
return IsUserAuthorized(hubIncomingInvokerContext.Hub.Context.Request);
}
protected bool IsUserAuthorized(IRequest thisRequest)
{
try
{
// Within the hub itself we can get the request directly from the context.
//Microsoft.AspNet.SignalR.IRequest myRequest = this.Context.Request; // Unfortunately this is a signalR IRequest, not a ServiceStack IRequest, but we can still use it to get the cookies.
bool perm = thisRequest.Cookies["ss-opt"].Value == "perm";
string sessionID = perm ? thisRequest.Cookies["ss-pid"].Value : thisRequest.Cookies["ss-id"].Value;
var sessionKey = SessionFeature.GetSessionKey(sessionID);
CustomUserSession session = HostContext.Cache.Get<CustomUserSession>(sessionKey);
return session.IsAuthenticated;
}
catch (Exception ex)
{
// probably not auth'd so no cookies, session etc.
}
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With