具有休息控制器的SpringMVC - 不支持请求方法“POST”

时间:2017-05-24 18:28:00

标签: spring rest csrf

我在SpringMVC中使用Spring Security进行应用程序。在spring security xml配置文件中,我使用<csrf/>启用csrf。当我将csrf令牌添加到表单链接时,在html中查看工作正常,但现在我想添加控制器并进行一些休息通信。控制器看起来像这样:

@Controller
public class RestControllerTest {   
    @RequestMapping(value = "/rest", method = RequestMethod.POST, produces = "application/json")
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody void setUser(@RequestBody User user){
        System.out.println("Witaj " + user.getFirstname() + "!");
    }
}

当我尝试向用户发送JSon时(使用邮递员):

{
  "firstname": "name",
  "lastname": "name"
}

我在邮递员中找到404未找到状态,在STS中找到WARN : org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported。我知道我必须使用csrf令牌,但我不知道如何做到这一点。 enter image description here

1 个答案:

答案 0 :(得分:1)

我有一个与你类似的工作用例。就我的情况而言,这就是事情。

我的过滤器类 -

public class MyCsrfFilter extends OncePerRequestFilter { 

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
        FilterChain filterChain)
            throws Exception {
        CsrfToken csrf = (CsrfToken) request.getAttribute(org.springframework.security.web.csrf.CsrfToken.class.getName());
        if (csrf != null) {
            Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
            String token = csrf.getToken();
            if (cookie == null) {
                cookie = new Cookie("XSRF-TOKEN", token);
                cookie.setPath(YOUR_DOMAIN_NAME);
                cookie.setHttpOnly(true);
                response.addCookie(cookie);
            }
        }
        filterChain.doFilter(request, response);
    }

}

以下是spring-boot中的安全配置。如果需要,可以将其转换为等效的xml配置文件。

@Configuration
@EnableWebMvcSecurity
public class CustomWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .csrfTokenRepository(getTokenRepo())
                .and()
                .authorizeRequests()
                .antMatchers("/login", "/login**").permitAll()
                .and()
                .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
    }

    private CsrfTokenRepository getTokenRepo() {
        HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
        repo.setHeaderName("X-XSRF-TOKEN");
        return repo;
      }

希望这有帮助!