0

I am trying to execute requests from angular js frontend to spring boot middle ware (spring boot 2.1.4) . The setup used to work as expected before I migrated the app to spring boot.

Post spring boot migration all the filter and security config from web XML has been configured in the form of annotated classes.

Now my requests from UI are getting rejected by spring boot with http 401 error with cors policy (Allowed-Origin)

My current project setup looks like this

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(customAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/**").hasAnyRole("ROLE_USER").anyRequest()
                .authenticated().and().csrf().csrfTokenRepository(csrfTokenRepository());
    }

    private CsrfTokenRepository csrfTokenRepository() {
        CustomDomainCookieCsrfTokenRepository repository = new CustomDomainCookieCsrfTokenRepository();
        repository.setCookieHttpOnly(false);
        return repository;
    }

}

@WebFilter("/*")
public class ForceCORSFilter extends OncePerRequestFilter {

    protected final Logger log = Logger.getLogger(this.getClass());
    private CacheService cacheService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            List<String> originList = getCacheService().getValidOriginUrI();
            String clientOrigin = request.getHeader("origin");
            if (clientOrigin == null) {
                // process the request even if origin is null
                processValidRequest(request, response, filterChain, clientOrigin);
            }
            if (clientOrigin != null) {
                // Origin should be validated if not null
                if (originList.contains(clientOrigin)) {
                    processValidRequest(request, response, filterChain, clientOrigin);
                } else {
                    log.info("####################### ORIGIN IS INVALID #######################" + clientOrigin);
                    filterChain.doFilter(request, response);
                }
            }
        } catch (Exception e) {
            response.getWriter()
                    .write("An error has occured while processing the request. Please retry with proper request.");
            log.info("An error has occured in the request " + e.getMessage());
        }
    }

    private void processValidRequest(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain,
            String clientOriginAllowed) throws IOException, ServletException {
        response.addHeader("Access-Control-Allow-Origin", clientOriginAllowed);
        response.addHeader("Access-Control-Allow-Credentials", "true");
        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD");
            response.addHeader("Access-Control-Allow-Headers",
                    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers,Authorization, X-XSRF-TOKEN");
        } else {
            filterChain.doFilter(request, response);
        }
    }

    public CacheService getCacheService() {
        return cacheService;
    }

    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

}

Can someone point out what is wrong here. Why I am still getting

http 401 "No 'Access-Control-Allow-Origin' header is present on the requested resource" errors.

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
Nishant Prabhu
  • 85
  • 1
  • 2
  • 11

1 Answers1

0

One issue might be precedence -- your filter isn't run at the right order. You can use @Order(Ordered.HIGHEST_PRECEDENCE) so it is run before the Spring Security filters.

Having said that, Spring has first-class support for CORS already, so there is no need to tediously define a filter at all. See the documentation and an example.

peekay
  • 1,885
  • 13
  • 11
  • Now I am getting http 405 error – Nishant Prabhu May 18 '19 at 10:40
  • Though all the request mappings are as it is in the mw.....the request from UI are getting 405 error. Any idea what this could be now ? – Nishant Prabhu May 18 '19 at 11:39
  • A common reason for a 405 is that the CSRF token is missing or invalid. If it's on a POST make sure the parameter is included. – peekay May 18 '19 at 11:45
  • It's a get request – Nishant Prabhu May 18 '19 at 14:25
  • I can see the XSRF-TOKEN in chrome with some value – Nishant Prabhu May 18 '19 at 15:00
  • If the request was a GET then the issue is probably not csrf related. Could be a RequestMapping issue. (For example, a 405 will be returned if the mapping is defined only for a POST but the request is a GET). Check in the spring boot logs, there should be a HttpRequestMethodNotSupportedException warning or something similar. You may want to open a new question with more details on the controller. – peekay May 18 '19 at 19:15