Search code examples
jqueryajaxspring-mvchttp-status-code-405

Spring MVC preauthorize Controller action not getting POST request


A noob at Spring MVC and Ajax stuff. I'm trying to send some data from the view to the controller using jQuery Ajax post but its either giving me 405 handleHttpRequestMethodNotSupported or 403 :-( Could someone please point me in the right direction?

This is my controller action that is preAuthorize.

@PreAuthorize( "hasAuthority('Admin')" )
@RequestMapping( value = "/configSave", method = RequestMethod.POST )
public String saveConfiguration( @RequestParam String test )
{
    return "configSave";
}

Following is the code from the page from where the post request is being sent.

...
<input type="button" value="Save" id="save" onclick="saveConfig()"/>
...
function saveConfig()
    {
        var testPost = { test: "testing"};

        $.ajax(
                {
                    url: "hello/configSave",
                    data: "{'test':'testing'}",
                    contentType: "application/x-www-form-urlencoded",
                    type: "post",
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("Accept", "application/json");
                        xhr.setRequestHeader("Content-Type", "application/json");
                    },
                    success: function () {
                        alert("foo");
                    },
                    error: function() {
                        alert("bar");
                    }
                }
        );
    }

All it does is it throws me either a 403 (for now, else 405) error with bar alert.

EDIT: Surprisingly, when I don't do ajax post (which I need to do) it calls the configSave action in the controller. Just really puzzled with this behaviour!


Solution

  • Managed to find a couple of sections in Spring docs this and this which says that I need to use CSRF token to send a post request across, when using Spring Security. After a lot of test and trail I found the following code working for me. I hope it helps others too. Any better suggestions are welcomed.

    ...<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>...
    
    ...<sec:csrfMetaTags />...//Within <head>
    
    ...var csrfToken = $("meta[name='_csrf']").attr("content");...//somewhere in page load
    
    function saveConfig()
        {
            var test = { name: "testing" };
    
            $.ajax(
                    {
                        url: "hello/configSave",
                        data: JSON.stringify( test ),
                        dataType: "text",
                        contentType: "application/json",
                        type: "post",
                        headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json',
                            'X-CSRF-TOKEN': csrfToken //adding this made it WORK!
                        },
                        success: function (msg) {
                            alert("Yippie! Saved");
                        },
                        error: function() {
                            alert("Save failed, please try again!");
                        }
                    }
            );
        }