[英]POST request to Spring server returns 403 forbidden
我已将 spring 服务器设置为响应包含 Message 对象的 POST 请求:
@RequestMapping(value = "/signup", method = RequestMethod.POST, consumes = "application/json")
public @ResponseBody Message signUp(@RequestBody Message message) {
logger.info("Accessing protected resource");
return new Message(100, "Congratulations!", "You have signed up. msg:"+message.toString());
}
Android 客户端设置为将请求发送为:
@Override
protected Message doInBackground(Void... params) {
// TODO Auto-generated method stub
final String url = "http://10.0.2.2:8080/signup";
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Message> requestEntity = new HttpEntity<Message>(signupmsg, requestHeaders);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
try {
// Make the network request
Log.d(TAG, url);
ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Message.class);
return response.getBody();
} catch (HttpClientErrorException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
return new Message(0, e.getStatusText(), e.getLocalizedMessage());
} catch (ResourceAccessException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
return new Message(0, e.getClass().getSimpleName(), e.getLocalizedMessage());
}
}
但是服务器总是返回 403 Forbidden 错误。 我希望它返回另一个 Message 对象 Message 对象是在单独的类中自定义定义的。 但是,如果我发送一个没有封装对象的 GET 请求,它就可以工作。 我是春天的新手。 我在这里缺少什么?
更新:我诊断出这个问题,当我启用 spring 网络安全时它就会发生。 没有安全性,POST 请求成功。 我尝试禁用配置中的安全性,但它仍然不起作用。 (虽然 GET 请求工作正常。)我目前在我的 WebSecurityConfiguration.java 中有以下内容
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.inMemoryAuthentication()
.withUser("roy")
.password("spring")
.roles("USER");
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().permitAll()
.and()
.httpBasic().disable();
// @formatter:on
}
我通过将以下内容添加到我的 build.gradle compile("org.springframework.boot:spring-boot-starter-security")
来启用网络安全
我尝试使用 REST 客户端使用浏览器发送 POST 请求,但它给出了错误:HTTP 状态 403 - 未找到预期的 CSRF 令牌。 你的会话过期了吗?
使用 .csrf().disable() 临时修复它
解决这个问题的最佳方法是什么?
我看到这是一个老问题,如果有人仍然遇到这个问题,解决方案很简单,您需要将“_csrf”令牌作为参数添加到您的请求中。 禁用它不是解决方案。 exchange() 方法也接受参数映射。
Map<String, Object> parameters = new HashMap<>();
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
parameters.put("_csrf", token);
restTemplate.exchange("url", HttpMethod.POST, requestEntity, Message.class, parameters);
更新如何检索 csrf 令牌:
Spring 通过名为“ServletRequestAttributes”的对象公开会话和请求对象,因此您可以执行以下操作:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder .currentRequestAttributes()) .getRequest();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.