每次尝试403 forbidden
来自数据库的用户信息时,我都会收到GET
错误。关于我下面的代码,每次我按 Ajax测试按钮尝试请求时,它都无法运行并给我一个警报,但在控制台中也给了我一个403 Forbidden
- 错误。我不确定它是否与Spring安全有关?
用户JSP页面:
<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>
用户控制器类:
@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;
}
答案 0 :(得分:22)
这通常是由Spring默认的CSRF保护引起的。
如果您使用JS代码中的DELETE HTTP请求,则还需要发送CSRF保护标头。
没有必要禁用CSRF保护!如果没有必要,请不要这样做。
您可以通过以下方式轻松添加CSRF AJAX / REST保护:
1.将元标题添加到每个页面(使用@ layout.html或其他内容):
<head>
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>
2.自定义您的ajax请求,以便为每个请求发送这些标头:
$(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);
});
});
请注意,我使用百里香,所以我使用th:content而不是content属性。
答案 1 :(得分:5)
如果您使用的是Spring Security 3.2R1及更高版本,请尝试使用此解决方案http://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection
答案 2 :(得分:2)
从Spring Security 4.0开始,默认情况下使用XML配置启用CSRF保护。如果要禁用CSRF保护,可以在下面看到相应的XML配置。
<security:http use-expressions="true">
...
<security:csrf disabled="true" />
</security:http>
答案 3 :(得分:1)
检查文件权限。 403是服务器错误,而不是Ajax。尝试直接检查所请求的文件(通过文件我的意思是网址)。
答案 4 :(得分:0)
在Spring Rest
或其他REST
实现(如Jersey
)中,如果服务器端没有匹配的资源,则REST容器会抛出403 Forbidden
。
您需要重新验证req-response批注。
例如,对于ajaxTest
请求,请尝试此更改:
@RequestMapping("/ajaxTest/{personid}", method=RequestMethod.GET)
@ResponseBody
public User ajaxTest(@PathVariable Integer personid) { .. }
基本上,person-id看起来不像请求参数(我们在GET
URL
中设置),尝试更改为PathVariable
,如果您不确定默认方法在Spring REST
中,明确定义应该调用此HTTP-Method
方法。
在403
上,它意味着operation not allowed
或许多类似的原因,除了身份验证失败。看看http://en.wikipedia.org/wiki/HTTP_403的各种可能性。