【问题标题】:Access-Control-Allow-Origin is missing缺少访问控制允许来源
【发布时间】:2021-05-30 22:53:41
【问题描述】:

我使用 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);
        }

【问题讨论】:

    标签: spring httprequest cross-origin-read-blocking


    【解决方案1】:

    只需在控制器上使用 @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() {
    }
    
    }
    

    【讨论】:

    • 我已经在所有控制器上添加了@CrossOrigin 注释并创建了上面的 bean,但仍然收到下面列出的错误 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at localhost:8080/trophy/AdminController/allAdmins. (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。跨域请求被阻止:同源策略不允许读取位于localhost:8080/trophy/AdminController/allAdmins 的远程资源。 (原因:CORS 请求未成功)。
    • @GurwinderSingh 我添加了一个编辑,试一试..
    • 嘿@k-wasilewski 我是否必须编写另一个过滤器来解决我现有的正在验证用户身份验证令牌的过滤器的丢失标头问题?
    • 不,你没有。只需将这些行添加到您现有的过滤器中即可。
    猜你喜欢
    • 2018-07-07
    • 2021-10-21
    • 2016-09-08
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2017-12-15
    相关资源
    最近更新 更多