Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR exception "Unrecognized user identity. The user identity cannot change during an active SignalR connection."

I have SignalR up and running on my MVC 4 application which uses Forms Authentication. I have the cookie timeout with sliding expiration set to 20 minutes.

I have a javascript function which runs on a timer so that after 20 mins and 1 second, it refreshes the page and the user is redirected to the Login page. It is important that I do this for security reasons and it works well.

My problem is that SignalR is throwing an InvalidOperation exception because the User identity has changed. I understand why it's doing this but am not sure how to avoid it.

I've tried calling $.connection.hub.stop(); before reloading the page but it does not work. I've tried calling it 5 seconds before the cookie expires but this only re-activates the session.

Any ideas would be appreciated!

Thanks John

like image 548
John Mc Avatar asked Nov 01 '22 10:11

John Mc


1 Answers

I was corresponding with David Fowler (the author of SignalR) on Github and he said there wasn't an easy way of resolving this.

To get around the problem, I implemented a Silent Logout controller action, which simply kills the users session.

    [HttpPost]
    [AjaxOnly]
    public ActionResult SilentLogOff()
    {
        _unitOfWork.WebSecurity.Logout();

        return Json(new
        {
            IsSuccess = true,
        });
    }

I then adjusted the JS timer to be 10 seconds short of the Forms authentication timeout. When it expires, it stops the SignalR hub connection, performs a POST to the SilentLogout action and then reloads the page.

SetLogoutTimer: function () {

    var formsTimeoutValue = $("#hdnRefreshTimeout").val();

    clearTimeout("formsTimeoutTimer");

    var formsTimeoutTimer = setTimeout(function () {
        $.connection.hub.stop();

        AppName.Authenticated.SilentLogoutUser();

    }, formsTimeoutValue);
}

SilentLogoutUser: function() {
    var url = $("#logout a").attr("data-bind-silent-url");
    $.ajax({
        type: "POST",
        url: url,
        success: function (response) {
            if (response.IsSuccess === true) {
                window.location.reload(true);
            }

        }
    });
}

This results in the correct behaviour in that there is no SignalR exception, and the user is redirected to the previous page they were on after re-authenticating.

like image 113
John Mc Avatar answered Nov 15 '22 04:11

John Mc