Check authorize in SignalR attribute

2020-08-21 02:55发布

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 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)


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!

2楼-- · 2020-08-21 03:35

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)

            // 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;
3楼-- · 2020-08-21 03:36

AuthorizeAttribute has two more virtual methods:

  • AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
  • AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)

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.

登录 后发表回答