U4-4149 - Controller Route Fails with 417 missing token

Created by Adrian Martin 28 Jan 2014, 09:33:33 Updated by Sebastiaan Janssen 22 Jun 2017, 07:56:00

Duplicates: U4-9873

I have been trying to add some backoffice functionality, I've set up a very basic Controller shell code to get started, its main action just returns "Hello World".

After attempting to browse the url to check things were working, I was getting 404s until I realised that 7.0.2 requires the /backoffice/ url part.

But know all I can get out of the Controller is a 417 Invalid token.

After Googling around a bit: Clearing cookies has not fixed the issue. Creating a new admin user and clearing cookies has not fixed the issue.

I'm stumped and I cant continue developing my code using a controller :-(

Comments

Sebastiaan Janssen 28 Jan 2014, 10:06:19

Have you tried in a different browser? Do you have example code so we can see what might be going wrong for you?

Also try the cache clearing tricks for Chrome / client dependency (see below) and make sure to set debug="true" in your web.config:

One way to nudge the cache in Chrome is to open the developer tools (F12) and go to the settings (the cog icon). There will be a checkbox that says "Disable cache (while DevTools is open)". Once this checkbox is on you can refresh the page and the cache should be invalidated. To force it even more, the "reload" button next to your address bar now has extra options when you right-click it. It should have "Normal reload", "Hard reload" and "Empty cache and hard reload" now. The last option is the most thorough and you might want to try that.

The important other thing you'll need to do is go into config/ClientDependency.config and update the version number in there. So if it currently says version="2" then just make it one higher: version="3". This will ensure that any server-side cache of javascript and stylesheets gets cleared as well.


Adrian Martin 28 Jan 2014, 10:22:10

I've tried Chrome Dev and IE11 so far same issue

I am using code copied from here http://umbraco.github.io/Belle/#/tutorials/Add-ServerSide-Data controller class supplied below:

At the end of "Setup the GetAll() method" section it asks you to test the url /umbraco/My/PersonApi/GetAll

and states it should return the data as JSON...

...I was just getting a 404

Now in 7.0.2 I noticed the urls have a /backoffice/ part ( I dumped the route table - but have since seen the .2 release notes).

...Now I'm getting a blank page and looking in the network panel I can see the 417

But now I've looked at the code on GitHub for UmbracoAuthorizedJsonController It starts with the note that the request must contain a valid CSRF header...

Looking at the cookies I'm sending they are UMB_CONTENT,XSRF-TOKEN,XSRF-V are the correct tokens?

using System; using System.Collections.Generic; using System.Linq; using System.Web;

using Umbraco.Web.WebApi; using Umbraco.Web.Editors; using Umbraco.Core.Persistence;

namespace My.Controllers { [Umbraco.Web.Mvc.PluginController("My")] public class PersonApiController : UmbracoAuthorizedJsonController { //we will add a method here later

    public IEnumerable<Person> GetAll()
    {
        List<Person> peeps = new List<Person>(){
             new Person(){Id=1, Name="Myles A. Pearson",Town="Tailles",Country="United Kingdom"}                            
            ,new Person(){Id=2, Name="Cora Y. Kelly"   ,Town="Froidchapelle",Country="Latvia"}
            ,new Person(){Id=3, Name="Brooke Baxter", Town="Mogi das Cruzes",Country="Grenada"}
            //,new Person(){"Illiana T. Strong","Bevel","Bhutan"}
            //,new Person(){"Kaye Frederick","Rothesay","Turkmenistan"}
            //,new Person(){"Erasmus Camacho","Sint-Pieters-Kapelle","Saint Vincent and The Grenadines"}
            //,new Person(){"Aimee Sampson","Hawera","Antigua and Barbuda"}
        };

        return peeps;

    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Town { get; set; }
        public string Country { get; set; }
    }
}

}


Markus Johansson 04 Mar 2014, 09:54:49

I have the same issue with a controller-action that I want to call without using Angular. Like this Download


Shannon Deminick 10 Mar 2014, 00:03:43

Do you have this issue with 7.0.3 or 7.0.4?


Markus Johansson 10 Mar 2014, 08:29:43

This is on version 7.0.4. It only when I'm using the UmbracoAuthorizedJsonController-class. My work around was to use the UmbracoAuthorizedApiController with like this:

[UmbracoUserTimeoutFilter] [global::Umbraco.Web.WebApi.UmbracoAuthorize] [PluginController(NewsletterStudioApplication.Name)] [IsBackOffice] public class DownloadController : UmbracoAuthorizedApiController

And I left out these attributes: [ValidateAngularAntiForgeryToken], [AngularJsonOnlyConfiguration].

I think that it's the ValidateAngularAntiForgeryToken-class that trows the error and I guess that this is probably not a bug but more expected behavior. What I'm doing here is to send back a file to the user so I guess that my use case is not that common with the WebAPI.


Shannon Deminick 10 Mar 2014, 23:23:40

Hi @Markus,

I guess this all depends on how you are calling your API controller and what you are using it for. If you have an API controller that is being used by angular for sending/receiving JSON then you'd def want to use UmbracoAuthorizedJsonController. In theory you should still use the UmbracoAuthorizedJsonController with the [ValidateAngularAntiForgeryToken] filter applied but you need to ensure you call your endpoints correctly - how are you currently calling them? When you are using angular's approach it will automatically set the correct request header based on the cookie values. If you are not using angular's approach then you'd need to set the headers correctly. The way it works is documented in angular: http://docs.angularjs.org/api/ng/service/$http See Security Considerations


Markus Johansson 11 Mar 2014, 09:25:47

I understand and thats why I don't really see this as a bug anymore. What I'm doing is redirecting the user to download a file. Download and then changing the headers of response from the API so that the browser know that it's a file. So from my point of view this is not a bug.


Robert Foster 30 Mar 2014, 11:36:38

I'm still having this issue on a 7.0.4 installation - I've got the website on Azure, and have verified that the XSRF cookie is being set by the SetAngularAntiForgeryTokens attribute on PostLogin, but the browser response headers only shows the UMB_CONTEXT cookie.

This problem is happening on both my local dev setup and the production Azure website.

I've managed to get this working again by either changing the database to a clean one, or by changing the IISExpress Port number in the application and running in Debug mode, but as soon as I go back to the original database and port number I face the same problem.

Clearing browser cache/cookies makes no difference to the issue.


Robert Foster 30 Mar 2014, 11:37:21

I've also compared the live database against a clean one and can't find anything that suggests the live database is causing the problem.

It's also browser agnostic - doesn't matter which browser I use, still have the same problem.


Markus Johansson 31 Mar 2014, 07:29:33

@rfoster are you calling the API from AngularJS or in any other way? As we have talked about above I don't really see this as a bug - more like a security feature.


Robert Foster 31 Mar 2014, 09:36:45

after reading through again it's a completely separate issue - I'm getting this from a vanilla Umbraco 7.0.4 install (well, vanilla + a few patches I applied but have no relevance to this).

Logging into Umbraco is not setting the cookie correctly, and thus everything else fails. clearing cache and cookies makes no difference that I can see.

I'm currently wondering whether it's a possible server-side cache issue.


Priority: Normal

Type: Bug

State: Duplicate

Assignee: Shannon Deminick

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.0.4, 7.4.3

Due in version:

Sprint:

Story Points:

Cycle: