Конфликт политики CORS при загрузке Spring - PullRequest
2 голосов
/ 25 июня 2019

Я новичок в весенней загрузке, и я реализовал некоторые основные REST API, используя весеннюю загрузку.И когда я попытался вызвать эти API-интерфейсы с помощью реагировать, у меня возникла ошибка при вызове некоторых политик CORS.Затем я нашел решение этой проблемы, и все мои конечные точки API работают правильно, за исключением вызова API входа в систему.Я получаю ту же ошибку при вызове:

enter image description here

Вот мой класс веб-безопасности Java.

@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {

    private final UserService userDetailsService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

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

        http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
                .permitAll().anyRequest().authenticated().and().cors().and().addFilter(getAuthenticationFilter())
                .addFilter(new AuthorizationFilter(authenticationManager())).sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }

    public AuthenticationFilter getAuthenticationFilter() throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
        filter.setFilterProcessesUrl("/users/login");
        return filter;
    }
}

А вот мой примерконтроллер класса.

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    UserService userService;

    @CrossOrigin
    @GetMapping(path = "/{id}", 
            produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
    public UserRest getUser(@PathVariable String id) {

        UserRest returnValue = new UserRest();

        UserDto userDto = userService.getUserByUserId(id);
        BeanUtils.copyProperties(userDto, returnValue);

        return returnValue;
    }

    @CrossOrigin
    @PostMapping(
            consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE }, 
            produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
    public UserRest createUser(@RequestBody UserDetailsRequestModel userDetails) {

        UserRest returnValue = new UserRest();

        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(userDetails, userDto);

        UserDto createUser = userService.createUser(userDto);
        BeanUtils.copyProperties(createUser, returnValue);

        return returnValue;
    }
}

Я застрял с этой проблемой, и мне действительно нужна помощь.Я попробовал некоторые ответы, данные в stackoverflow, как похожие на мою проблему.Но это не решило мою проблему.Mt весенняя загрузка версии 2.1.4

Ответы [ 2 ]

4 голосов
/ 26 июня 2019

Вы столкнулись с проблемой, потому что вы допустили cors на своем бэкенде от порта 8080, но ваша реакция на порту 3000 на локальном. Так, springboot не примет запрос, поскольку он приходит с другого адреса порта.

Метод 1:

Вы можете избежать неприятностей, используя аннотацию, такую ​​как:

@CrossOrigin(origins = "http://localhost:3000", maxAge = 3600)

Поскольку вы используете springboot, вы также можете использовать следующую глобальную конфигурацию, чтобы определить, какие домены имеют доступ к вашему бэкэнду.

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000")
                    .allowedMethods("PUT", "DELETE", "GET", "POST") //or allow all as you like
                    .allowedHeaders("header1", "header2", "header3")
                    .exposedHeaders("header1", "header2")
                    .allowCredentials(false).maxAge(3600);
             }
        };
    }
}

и если у вас все еще есть проблемы, это может быть связано с тем, что система безопасности Spring не добавляет заголовки CORS , как Access-Control-Allow-Origin, в ваш заголовок ответа . В этом случае вы можете определить собственный фильтр CORS и добавить его в систему безопасности Spring, чтобы заголовки ответов CORS были установлены для всех конечных точек безопасности Spring. Вы можете создать bean-компонент фильтра, например:

public class CorsFilter implements Filter {

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request= (HttpServletRequest) servletRequest;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", true);
        response.setHeader("Access-Control-Max-Age", 180);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Метод 2:

, поскольку вы используете пружинную защиту , вы также можете добавить конфигурацию CORS вместе с пружинной защитой, например:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            //other configurations that you want
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource()
    {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        //or any domain that you want to restrict to 
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        //Add the method support as you like
        UrlBasedCorsConfigurationSource source = new     UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
} 

Spring security будет принимать конфигурацию CORS, даже если вы предоставите ее, как в методе 1, насколько мне известно. Но в документации Spring они также предусмотрели этот способ регистрации CORS с защитой Spring.

В прикрепленном журнале консоли , который вы прикрепили, говорится, что проверка перед полетом не удалась из-за возврата http-статуса, не в порядке. Так что вы можете попробовать зарегистрировать cors, как метод 2, и добавить фильтр так что заголовки добавляются правильно в ответ. Springboot блокирует предполетную проверку при входе на страницу входа. Вам необходимо правильно настроить ваши cors с помощью Spring Security, чтобы разрешить доступ к странице входа из другого порта.

Подтвердите, что на вашей странице входа в систему /login сопоставление разрешено CORS

Официальный Док Справочник Документ

1 голос
/ 25 июня 2019

Попробуйте,

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("*");
    }
}

Обновите

Вы также можете сделать следующее,

@Bean
public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Collections.singletonList("*"));
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> filterRegistration = new FilterRegistrationBean<>(new CorsFilter(source));
        filterRegistration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return filterRegistration;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...