spring security with angular2 giving 403 forbidden

2019-09-14 20:08发布

I have spring mvc(rest), spring security(4.x) and angular2 application. App is deployed in weblogic and it takes care of SAML authentication, so my app is just using authorization piece only. To do that we are using custom request header authentication filter where we validate custom request header and based on that loads user from db with granted authority. All this works fine.

Now I am implementing CSRF protection where my server is adding CSRF token cookie and since angular2 is has out of the box support for this it is passing same cookie as x-xsrf-token on all subsequent requests.

Problem starts here where all GET requests are working fine but when my app does POST or PUT or DELETE, it is getting 403 error. Comparing GET and POST request, I noticed that POST request does not have "Access-Control-Allow-Headers", so I am thinking that somehow my server has to expose this headers, so that browser can send X-XSRF-TOKEN for POST/PUT request.

Same headers are present on GET request.

Can anyone explain am I on the right track or not? If yes, then how can I expose this headers in spring secuirty or spring mvc for whole application?

If not then what is causing this issue?

My CORS config

<filter>
  <filter-name>cors</filter-name>
  <filter-class>com.elm.mb.rest.filters.CORSFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>cors</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>


@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    response.addHeader("Access-Control-Allow-Origin", "*");

    if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
        LOG.trace("Sending Header....");
        // CORS "pre-flight" request
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type,X-XSRF-TOKEN");
        response.addHeader("Access-Control-Max-Age", "1");
    }

    filterChain.doFilter(request, response);
}

1条回答
甜甜的少女心
2楼-- · 2019-09-14 20:39

You should return the preflight request directly, more see here (not-so-simple requests).

if (request.getHeader("Access-Control-Request-Method") != null) {
    LOG.trace("Sending Header....");
    // CORS "pre-flight" request
    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type,X-XSRF-TOKEN");
    response.addHeader("Access-Control-Max-Age", "1");  
    if ("OPTIONS".equals(request.getMethod())) {
        return ;
    }
}
查看更多
登录 后发表回答