简体   繁体   中英

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!

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM