如何在 Spring MVC 中启用 CORS 进行错误响应?

问题描述 投票:0回答:3

我正在开发一个应用程序,我使用 Spring MVC 作为后端,使用 Angular5 作为前端。我一直坚持 Auth2 安全层的实现,包括跨源资源共享。我的 CORS 过滤器实现如下所示:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@WebFilter("/*")
public class WebSecurityCorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, x-requested-with, Cache-Control");


        if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
            res.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(request, res);
        }

    }
    @Override
    public void destroy() {
    }
}

我工作得几乎正常,我能够获取 access_token 并使用它从 ResourcesServer 获取受保护的数据:

{“access_token”:“4fcef1f8-4306-4047-9d4d-1c3cf74ecc44”,“token_type”:“承载”,“refresh_token”:“397016eb-dfb0-4944-a2e0-50c3bd07c250”,“expires_in”:29,“范围“:“读 写信任”}

Browser console screenshot

当我尝试使用过期令牌处理请求时,问题就开始了。在这种情况下,我无法通过 Angular 捕获正确的 ErrorResponeCode。 Angular HttpClient 得到的不是 401,而是状态为 0 的“未知错误”。

问题似乎出在 CORS 策略上,其中 ErrorResponse 不包含必需的标头,例如 Access-Control-Allow-Origin (...)

加载失败http://localhost:8030/api/xxxx:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此,不允许使用 'http://localhost:8070' 使用权。响应的 HTTP 状态代码为 401。

ErrorResponse Headers - Screenshot

我搜索了如何在 Spring MVC 中为 ErorrResponse (InvalidTokenException 等)启用 CORS。我尝试了各种方法:accessDeniedHandler 和 setExceptionTranslator 但没有成功。我确实努力自己寻找解决方案,但我是 Spring 的初学者。我不确定这是否可能。

角度(更新)

@hrdkisback,这不是角度问题,无论如何这是我的代码:

@Injectable()

export class HttpInterceptorService implements HttpInterceptor {


    addToken(req: HttpRequest<any>, oauthService: AuthenticationService): HttpRequest<any> {

        if(oauthService.isTokenExist()){

            return req.clone({ setHeaders: { Authorization: 'Bearer ' + oauthService.getAccessToken() }})
        }

        return req;
    }


    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {

        let oauthService = this.inj.get(AuthenticationService);

        return next.handle(this.addToken(req,oauthService))

        .do((event: HttpEvent<any>) => {

            if (event instanceof HttpResponse) {

                // process successful responses here

            }
        }, (error: any) => { 

            if (error instanceof HttpErrorResponse) {

                // Error 

                console.log(error);
            }
        });

    }
}
spring angular spring-mvc oauth-2.0 cors
3个回答
2
投票

在 ResourcesServer 配置级别添加 CORS 过滤器后,问题得到解决,如下所示:

适合我的正确配置!

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {


    @Override
        public void configure(HttpSecurity http) throws Exception {

            http
            .addFilterAfter(new WebSecurityCorsFilter(), CsrfFilter.class)
            ...
        }
   ....
}

在我之前的配置中,我以相同的方式添加了过滤器,但在 MVC 安全配置的顶层,这是我的问题的根源:

导致我出现问题的先前配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {



    @Override
            public void configure(HttpSecurity http) throws Exception {

                http
                .addFilterAfter(new WebSecurityCorsFilter(), CsrfFilter.class)
                ...
            }
       ....
    }

0
投票

我遇到了同样的问题..我正在尝试使用 Angular 5 进行基本身份验证。 问题是您没有在错误响应中添加 CORS 标头。 这就是我所做的

@Component
public class AuthEntryPoint extends BasicAuthenticationEntryPoint {

@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
  throws IOException, ServletException {
    response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());
    response.addHeader("Access-Control-Allow-Origin", "http://localhost:4200");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    PrintWriter writer = response.getWriter();
    writer.println("HTTP Status 401 - " + authEx.getMessage());
    }
}

这样就可以了!


0
投票
i have facing same issue react.js with Spring mvc.can you provide me steps how to solve this problem.The above class as you mentioned where is to be declared? and after declaration what next do ? please provide each and every steps.
© www.soinside.com 2019 - 2024. All rights reserved.