SignalR 2.0 Authorization

I have a form-checking web server and another server hosting SignalR hubs. Using a cookie to authenticate forms, I want to extract the current user using the following code. This would be possible using the HttpModule, but when using SignalR you cannot use the HttpModule.

Is there any other way of archiving what I want to do?

public class AuthorizationHubModule : HubPipelineModule { public AuthorizationHubModule() { } protected override bool OnBeforeConnect(IHub hub) { var cookies = hub.Context.Request.Cookies; if (cookies.ContainsKey(".ASPXAUTH") == true) { // Get the user, populate the Thread.CurrentUser... Cookie cookie = cookies[".ASPXAUTH"]; if (cookie != null) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); GenericIdentity identity = new GenericIdentity(ticket.Name); GenericPrincipal principal = new GenericPrincipal(identity, new string[0]); // Cannot do this because User is readonly (this is possible in a normal HttpModule) //hub.Context.User = principal; } } return base.OnBeforeConnect(hub); } } 

What we need is to set the IPrincipal associated with SignalR.

+1
source share
3 answers

If I am not mistaken, you are trying to extract the user information of the registered user from the context. If this is correct, this can simply be achieved by following these steps:

  • Add the [Authorize] attribute for your hub class.
  • Then use Context.User.Identity to get the user id.

Since you are using a persistent connection, the authorization process should be considered by you. Refer to this link and you can customize the code provided there to suit your needs.

To change the request identifier, you must add FormsAuthentication_OnAuthenticate to your global.asax. Here is an example of the code I wrote for my application:

 protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e) { if (FormsAuthentication.CookiesSupported == true) { if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) { try { string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name; //Let us set the Pricipal with our user specific details e.User = new System.Security.Principal.GenericPrincipal( new System.Security.Principal.GenericIdentity(username, "Forms"), _user.GetUserRoles(username)); } catch (Exception) { //somehting went wrong } } } } 

Hope this helps.

+1
source

It turns out that Signal-R cannot change the associated IPrincipal because SignalR is not intended for authentication, but it gets the authentication context from the application. So the right way to do this, as @Shashank pointed out, is to use Forms or whatever you use in your application, and SignalR will get this context from it.

+1
source

Implement the IUserIdProvider interface and add it using

 GlobalHost.Configuration.Resolver.Register(typeof(IUserIdProvider), () => provider.Object); 

You can read it here .

0
source

Source: https://habr.com/ru/post/1268386/


All Articles