Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

403 Forbidden Error with ajax GET request Spring

I am getting a 403 forbidden-error every time I try GET a user's information from the database. Relating to my code below, every time I try request by pressing the Ajax Test button, It fails to run and gives me an alert, but also in the console gives me a 403 Forbidden-error. I am not sure whether it has something to do with Spring security?

Users JSP page:

<table>
    <tr>
        <td>User Id</td>
        <td>Full Name</td>
        <td>Username</td>
        <td>Email</td>
        <td>Date of Birth</td>
        <td>User Authority</td>
        <td>Update </td>
        <td>Delete</td>
    </tr>
    <c:forEach var="user" items="${users}">
        <tr>
            <td><c:out value="${user.id}" /></td>
            <td><c:out value="${user.name}"/></td>
            <td><c:out value="${user.username}"/></td>
            <td><c:out value="${user.email}"/></td>
            <td><c:out value="${user.dob}"/></td>
            <td><c:out value="${user.authority}"/></td>
            <td>
                <a id="update" href="<c:url value="/viewUser"><c:param name="id" value="${user.id}"/></c:url>"><button>Update</button></a>
            </td>
            <td>
                <a id="delete" href="<c:url value="/deleteUser"><c:param name="id" value="${user.id}"/></c:url>"><button>Delete</button></a>
            </td>
            <td>
                <button class="loadUser" name="id" value="${user.id}">Ajax test</button>
            </td>
        </tr>
    </c:forEach>
</table>
 <div id="personIdResponse"> </div>
<script type="text/javascript">
    $(document).ready(function(){
        $(".loadUser").click(function(e) {
            e.preventDefault();
            var personId = +$(this).val();
            $.get('${pageContext.request.contextPath}/SDP/ajaxTest/' + personId, function(user) {
                  $('#personIdResponse').text(user.name + ', = username ' + user.username);
                })
            .fail(function(user){
                alert('Could not load user');
            });
        });
    });
</script>

User Controller class:

    @RequestMapping("/viewUser")
public String updateUser(Model model, @RequestParam(value = "id", required = false) Integer id) {

    User user = usersService.getUser(id);

    model.addAttribute("user", user);

    return "settings";
}

@RequestMapping("/ajaxTest")
@ResponseBody
public User ajaxTest(@RequestParam(value = "id", required = false) Integer id) {

    User user = usersService.getUser(id); 
    return user;
}
like image 770
Maff Avatar asked Sep 30 '13 09:09

Maff


People also ask

How do I fix 403 Forbidden in Java?

Double Check the Address. The most common reason for a 403 error is a mistyped URL. First, ensure that the address you are trying to access is for a web page or file, not a directory. For example, a regular URL would end in .com, .

What does Ajax error 403 mean?

The HTTP 403 Forbidden response status code indicates that the server understands the request but refuses to authorize it. This status is similar to 401 , but for the 403 Forbidden status code, re-authenticating makes no difference.

How to get a 403 Error?

The 403 Forbidden error appears when your server denies you permission to access a page on your site. This is mainly caused by a faulty security plugin, a corrupt . htaccess file, or incorrect file permissions on your server.

Does spring use Ajax?

Summary. Spring 3 provides first-class Ajax support with JSON as part of the Spring MVC module. This includes support for generating JSON responses and binding JSON requests using the Spring MVC @Controller programming model in conjunction with the Jackson JSON processor.


2 Answers

It is usually caused by Spring default CSRF protection.

If you use for example DELETE HTTP request from your JS code, it is required to send also CSRF protection headers.

It is not necessary to disable CSRF protection! Please, do not do that if not necessary.

You can easily add CSRF AJAX/REST protection by:

1.Adding meta headers to every page (use @layout.html or something):

<head>
  <meta name="_csrf" th:content="${_csrf.token}"/>
  <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>

2.Customizing your ajax requests to sent these headers for every request:

$(function () {
  var token = $("meta[name='_csrf']").attr("content");
  var header = $("meta[name='_csrf_header']").attr("content");
  $(document).ajaxSend(function(e, xhr, options) {
    xhr.setRequestHeader(header, token);
  });
});

Notice that i use thymeleaf, so i use th:content instead of content attribute.

like image 70
lukyer Avatar answered Dec 27 '22 19:12

lukyer


If you are using Spring Security 3.2R1 and above try using this solution http://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection

like image 25
chege Avatar answered Dec 27 '22 20:12

chege