New to Telerik Reporting? Download free 30-day trial

Anti-Forgery Token Issue in ASP.NET Core 2.1+ Applications

Environment

Product Progress® Telerik® Reporting
Project Type ASP.NET Core, ASP.NET Core MVC
Viewer Type HTML5 Report Viewer

Description

When adding any of the following lines of code in the Startup.cs file, the report won't load and an error will be thrown.

Error Messages

One of the following error messages may occur:

services.AddMvc(options =>
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.AutoValidateAntiforgeryTokenAttribute()));

or

services.AddControllersWithViews(options =>
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.AutoValidateAntiforgeryTokenAttribute()));

Steps to Reproduce

  1. Implement the anti-forgery token. For example, in ASP.NET Core MVC application, create a new GetAntiXsrfRequestToken() function on the viewer page to get the request token:

    @inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
    @functions{
        public string GetAntiXsrfRequestToken()
        {
            return Xsrf.GetAndStoreTokens(Context).RequestToken;
        }
    }
    
  2. Add the function to each request header:

    <script type="text/javascript">
            $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
                jqXHR.setRequestHeader("__RequestVerificationToken", '@GetAntiXsrfRequestToken()');
            });
    </script>
    

As a result the viewer shows the exception message Error registering the viewer with the service..

And, in the browser console the Register Client request returns 400 Bad Request with the following error message:

Failed to load resource: the server responded with a status of 400 (Bad Request)
Uncaught (in promise) Invalid clientID

Solutions

The AutoValidateAntiforgeryToken is recommended by Microsoft for non-API scenarios. When using this approach, that requires manually adding anti-forgery attributes. If you forget the attribute, no error will occur and the Controller/Action will not be protected. For that reason, the automatic approach is generally less error-prone and easier to maintain, especially if there are large number of Controllers and Actions that need this protection. You can use the AutoValidateAntiforgeryToken with the ReportsController provided that you do one of the following things:

  • Add the IgnoreAntiforgeryToken attribute to the ReportsController. For example:

    [Route("api/reports")]
    [IgnoreAntiforgeryToken]
    public class ReportsController : ReportsControllerBase
    {
        //...
    }
    
  • Override all ReportsController public methods and add the IgnoreAntiforgeryToken attribute to them. You may skip the GET HTTP methods.

    [IgnoreAntiforgeryToken]
    public override IActionResult RegisterClient()
    {
        return base.RegisterClient();
    }
    

Alternatively, remove the auto anti-forgery configuration and decorate each controller or action that has to be protected against anti-forgery with the AutoValidateAntiforgeryToken or ValidateAntiforgeryToken attribute.

The following configuration or its equivalent:

services.AddMvc(options => { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); });

have to be replaced with the configuration:

services.AddMvc();
services.AddAntiforgery(options => options.HeaderName = "__RequestVerificationToken");

See Also

In this article