NullPointerException при выполнении запроса OPTIONS с помощью Access-Control-Request-Method в Spring-data-rest

Я получаю следующее исключение при выполнении запроса OPTIONS:

java.lang.NullPointerException: null
at org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.exposeEffectiveLookupPathKey(RepositoryRestHandlerMapping.java:264) ~[spring-data-rest-webmvc-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.lookupHandlerMethod(RepositoryRestHandlerMapping.java:165) ~[spring-data-rest-webmvc-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:368) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:65) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:401) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping$HandlerSelectionResult.from(DelegatingHandlerMapping.java:108) ~[spring-data-rest-webmvc-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping.getHandler(DelegatingHandlerMapping.java:74) ~[spring-data-rest-webmvc-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1231) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1014) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doOptions(FrameworkServlet.java:944) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:669) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.

Я делаю запрос:

curl 'http://localhost:9091/api/authors' -X OPTIONS -H 'Access-Control-Request-Method: GET' -H 'Origin: http://localhost:3000'

Я делаю это, чтобы имитировать предварительный запрос от моего внешнего интерфейса, где я изначально заметил проблему.

Если я удаляю из запроса заголовок «Access-Control-Request-Method», все проходит нормально.

Я использую SpringBoot версии 2.1.1. Вот мои зависимости:

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-security')
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')
    runtimeOnly('com.h2database:h2')
    testImplementation('org.springframework.boot:spring-boot-starter-test')

    compile 'org.springframework.boot:spring-boot-starter-data-rest:2.0.3.RELEASE'
}

и это моя конфигурация безопасности:

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

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

Вы можете найти демонстрационный проект здесь: https://github.com/cekali/spring-проблема

Я очень ценю любую помощь, которую кто-либо может предоставить, я в тупике

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
680
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

это ошибка в методе RepositoryRestHandlerMappingexposeEffectiveLookupPathKey. Хотя это было исправлено на Github, последней версии (3.1.4.RELEASE), к сожалению, не было.

Дальнейшая информация: Исключение выдается, потому что метод ожидает объект RequestMappingInfo, который инкапсулирует информацию из аннотации @RequestMapping на HandlerMethod. Но для предварительных запросов возвращаемый и впоследствии используемый HandlerMethod (см. AbstractHandlerMethodMapping) не имеет такой аннотации, поэтому объект RequestMappingInfo — это null. Вызов методов на нем, конечно же, вызовет NullPointerException.

Это исправление вы увидите на Гитхаб:

private void exposeEffectiveLookupPathKey(HandlerMethod method, HttpServletRequest request, String repositoryBasePath) {

    RequestMappingInfo mappingInfo = getMappingForMethod(method.getMethod(), method.getBeanType());

    if (mappingInfo == null) {
        return;
    }

    ...
}

ОБНОВИТЬ Это было исправлено в версии 3.1.5.RELEASE.

какие-нибудь мысли о том, как я могу исправить это в своем приложении? Мое решение на данный момент - понизить версию spring-boot до 2.0.5.RELEASE.

cekali 13.02.2019 17:54

Вы можете настроить свои предварительные запросы следующим образом:

У меня есть пользователь Spring Boot 2.1.3.RELEASE

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.cors().and()       
        .authorizeRequests()
        .antMatchers("/**",).permitAll() //custom logic
        ...................
        .............
    }


    //define the Corsbean and add your cutom headers here
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
         CorsConfiguration configuration = new CorsConfiguration();
         configuration.setAllowedOrigins(Arrays.asList("*"));
         configuration.setAllowCredentials(true);
         configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers","Access-Control-Allow-Origin",
                 "Access-Control-Request-Method", "Access-Control-Request-Headers","Origin","Cache-Control",
                 "Content-Type", "Authorization"));
         configuration.setAllowedOrigins(Arrays.asList("*"));
         configuration.setAllowedMethods(Arrays.asList("*"));
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
         source.registerCorsConfiguration("/**", configuration);
         return source;
     }

}

Другие вопросы по теме