9

I'm seeing lots of entries in my logs from this request:

/signalr/negotiate

The error is:

The controller for path '/Account/Login' was not found or does not implement IController

I have a JS client connecting to an AppHub that requires authentication:

[Authorize]
[HubName("appHub")]
public class AppHub : Hub
{
    // content
}

This is happening because there's an 'signalr` session alive with an expired cookie attempting to connect:

  • I'm not sure why the request is automatically seeking out this page. It's not specified anywhere in my web.config, routes, or elsewhere. Why is this happening?
  • I'd like to prevent the signalR client from attempting to connect if the user is unauthenticated. How can this be achieved?
SB2055
  • 10,654
  • 29
  • 87
  • 185

3 Answers3

4

If I understand your issue correctly then you are going to want to create your own custom class to handle this by inheriting the AuthorizeAttribute class: https://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx

For example:

public class MyCustAuthorize : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
        else
        {
            //modify this to do whatever you want to happen if unauthorized
            filterContext.Result = new RedirectResult("/session/noaccess/");
        }

    }

}

Then you can decorate it with your custom class instead of the default authorize (example is from a mvc controller but should be able to function the same on your hub) So this:

[Authorize]
public class AdminController : Controller
{

Becomes this:

[MyCustAuthorize]
public class AdminController : Controller
{

I believe the /Account/Login is the default path for forms auth so that is why it is directing there if it is not defined within your config file.

Alternatively you could insert the specific url to redirect to if that is what you are searching for by placing the following loginUrl attribute value in your auth section > forms element in the web.config:

Travis Acton
  • 3,846
  • 2
  • 16
  • 24
1

It looks like this may be similar to these other answers to questions already asked here and these may provide your solution:

Stackoverflow 1

Stackoverflow 2

Have you tried stopping the connection in the client when they are no longer authorized?

 $.connection.hub.stop();
Frank M
  • 946
  • 6
  • 12
  • I have [Authorize] on my entire hub (see question). The user becomes unauthenticated, and the signalR client continues to try to `reconnect`, leading to a ton of requests to `Account/Login`. I'm trying to prevent these requests. – SB2055 Aug 09 '17 at 17:49
  • The client should stop if it cannot reconnect within a reconnect timeout. – Pawel Aug 09 '17 at 18:27
0

Your app is using FormsAuthentication, so the Authorize attribute is redirecting to the login page by default when it fails to authorize.

You can disable this by adding the following to your web.config:

<modules runAllManagedModulesForAllRequests="true">
  <remove name="FormsAuthentication" />
</modules>

This will remove all the default behaviors.

You might have something in your app.config that looks like

<membership defaultProvider="ClientAuthenticationMembershipProvider">
  <providers>
    <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
  </providers>
</membership>

Which is what is adding these default behaviors for you.

Joe Pontani
  • 451
  • 4
  • 13