Параметры службы Spring boot rest 401 на OAuth / токене

Я использую spring boot, чтобы сделать простой сервис rest. Чтобы использовать его в Angular 2, у меня есть проблема CORS при получении токена на конечной точке oauth/token.

сообщение об ошибке в Chrome ниже.

сообщение об ошибке

zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token 
XMLHttpRequest cannot load http://192.168.0.9:8080/api/oauth/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.

связанные файлы приведены ниже.

MyConfig.java

@Configuration
public class MyConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("**")
                        .allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS")
                .allowCredentials(true)
                .allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials")
                .maxAge(10);
            }
        };
    }
}

OAuth2ResourceServerConfig.java

@Configuration
@EnableResourceServer
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .anonymous()
            .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS,"**").permitAll()
                .antMatchers("/authenticated/**").authenticated()
                ;
    }

}

Я новичок в java и spring. Я нашел аналогичный вопрос, такие как OAuth2-статус 401 по запросу опций при получении токена, но я действительно не понимаю, как заставить его работать в spring boot.

обратите внимание, что нормальная конечная точка контроллера rest работает нормально. Проблема в oauth / token, запрос options возвращает состояние 401.

пожалуйста, покажите мне рабочий код в spring boot. Спасибо!

3 ответов


вы можете добавить этот фильтр CORS в свой проект

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)

public class SimpleCORSFilter implements Filter {

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

@Override
public void doFilter(ServletRequest req, ServletResponse resp,
        FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) resp;
    HttpServletRequest request = (HttpServletRequest) req;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");

    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
    } else {
        chain.doFilter(req, resp);
    }

}

@Override
public void destroy() {
}

}

вот собственное решение Spring Framework:

@Bean
public CorsFilter corsFilter(CorsConfiguration config) {
    log.debug("Registering CORS filter");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", config);
    source.registerCorsConfiguration("/v2/api-docs", config);
    source.registerCorsConfiguration("/oauth/**", config);
    return new CorsFilter(source);
}

Если вы используете spring boot + Spring OAuth, вы должны добавить

@Order(Ordered.HIGHEST_PRECEDENCE)

к вашему фильтру CORS

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {

    private FilterConfig config;

    public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
    public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
    public static final String METHODS_NAME = "Access-Control-Allow-Methods";
    public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
    public static final String MAX_AGE_NAME = "Access-Control-Max-Age";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, resp);
        }

    }

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