Failed to read the 'localStorage' property from 'Window'

Viewed 490

I understand what my error message means, cookies are disabled. However, I am trying to graciously handle this scenario and I am not quite sure how.

I am using MVC Core and here is what happens. When I try to use third-party authentication such as Google and cookies are disabled, my website loads a white page and my controllers are never hit. I wanted to do a check on my controller to see if cookies are disabled, but it never reaches that far.

Digging around online, the only way to check if cookies are disabled is to set a cookie, redirect to another page and read the cookie. However, with MVC core I can't seem to even be able to do that.

My suspicion is that ValidateAntiForgery attribute or AuthorizeFilter kicks in and tries to do its thing and crashes cause it can't read cookies. However, what I find really weird here is that my global error handling doesn't catch it. I don't even get an error page, I just get a white page.

How to get around this?

EDIT:

So the testing I have done was in Chrome and that is the behavior. If I try this on IE 11 it kicks me to Google page. Why would Chrome not?

EDIT 2:

If I remove ValidateAntiForgery Attribute then I have no problems.

Code:

var schemes = await SchemeProvider.GetAllSchemesAsync();
var loginProviders = schemes.ToList();
if (loginProviders.Any())
{
    <form id="form-login" asp-controller="Login" asp-action="ExternalLogin" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post">
        @{
            var provider = loginProviders.FirstOrDefault(t => t.Name.Equals("Google"));
        }
        @if (provider != null)
        {
            <input type="hidden" name="provider" value="@provider.Name"/>
        }
    </form>
}

OUTPUT:

<form id="form-login" method="post" action="/MySite/Login/ExternalLogin">
    <input type="hidden" name="provider" value="Google">
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8H5fggDmaa5Alubd0Uq6Sdi5ck0sJteuBr7cgnyqRX_x9_U4CTZzOB-2iiToQ6dyugjPgirRWnfazcgRXwvFIn5xMyLUVAd9wSG_CgLGtKWjgG0X8_SKfWwMFQiww3UfHHE04PPxbdIovktDrMu1BR4">
</form>

To Activate it, I have a simple onclick from javascript:

$("#login").on('click', function (e) {
    e.preventDefault();
    $("#form-login").submit();
});
1 Answers

I wanted to provide an update as to why this happens as I have it figured out. When ValidateAntiForgeryAttribute is kicked in, it calls the ValidateAntiForgeryFilter. In that filter, there is a try-catch if the validation fails. If the catch is called it then creates a new BadRequest.

Now the problem is that this BadRequest is not caught by the global handling filter I have injected in startup. This is a problem with the core framework itself.

To temporarily solve it, I have rewritten the ValidateAntiForgeryAttribute and ValidateAntiForgeryFilter and removed the try/catch. This will cause my page to error out and while it is not the ideal solution it will not produce that white page for the user but something more generic which now I can identify in my global error handler and give a user a better experience.

There are a couple of issues opened on github that I found in regards to this issue:

https://github.com/aspnet/Home/issues/2190
https://github.com/aspnet/Mvc/issues/6678

Related