Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check authorize in SignalR attribute

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!

like image 464
Alexander Krylov Avatar asked Mar 26 '14 01:03

Alexander Krylov


People also ask

What is the authorize attribute in SignalR?

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.

How do I access authentication data in a SignalR 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.

How do I associate a user with a connection 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.

What happens if the authorize attribute is not applied?

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:


2 Answers

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.

like image 177
halter73 Avatar answered Sep 22 '22 01:09

halter73


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;
    }
}
like image 43
DannyW Avatar answered Sep 18 '22 01:09

DannyW