问题描述
我使用 Spring 4 作为我的 angular 应用程序的后端。当 angular 应用程序向 spring 应用程序发出请求时,我收到一个错误
Access to **XMLHttpRequest at 'http://localhost:8080/AdminController/allAdmins' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.**
我正在使用自定义过滤器来验证每个用户请求 我的过滤器的代码是:
@Override
public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain) throws IOException,servletexception {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpResp = (HttpServletResponse) response;
// Ignoring the request URLs
if (Utils.ignoreURLs(IGnorE_URLS,httpReq.getRequestURI()) == true) {
filterChain.doFilter(request,response);
return;
}
// Fetching all the header params from request
HttpServletRequest httpRequest = (HttpServletRequest) httpReq;
Enumeration<String> headerNames = httpRequest.getHeaderNames();
String loggedUserId = null;
String authToken = null;
if (headerNames != null) {
while (headerNames.nextElement() != null && headerNames.hasMoreElements()) {
loggedUserId = httpRequest.getHeader(Constants.LOGGED_USER_ID);
authToken = httpRequest.getHeader(Constants.AUTH_TOKEN);
}
}
if (Utils.isBlank(loggedUserId) == true || Utils.isBlank(authToken) == true) {
httpResp.setContentType(MediaType.APPLICATION_JSON_VALUE);
mapper.writeValue(httpResp.getWriter(),getErrorDetailsMap());
return;
}
ApplicationContext appContext = AppContextConfig.getApplicationContext();
AccessManager accessManager = (AccessManager) appContext.getBean(AccessManager.class);
// I am validating authentication token here
if(accessManager.isValidToken(loggedUserId,authToken) == false) {
httpResp.setContentType(MediaType.APPLICATION_JSON_VALUE);
mapper.writeValue(httpResp.getWriter(),getErrorDetailsMap());
return;
}
filterChain.doFilter(request,response);
}
解决方法
只需在控制器上使用 @CrossOrigin
注释并在您的 SecurityConfig 中定义此 bean:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token","xsrf-token"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",configuration);
return source;
}
编辑
或者可能是缺少标头的问题,其中以下过滤器应该足够了。
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SimpleCORSFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException,ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE");
response.setHeader("Access-Control-Max-Age","3600");
response.setHeader("Access-Control-Allow-Headers","Content-Type,Accept,X-Requested-With,remember-me");
chain.doFilter(req,res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}