Проблема весеннего облачного шлюза Нет альтернативных имен субъектов

Проблема #Spring Cloud Gateway Отсутствуют альтернативные имена субъектов

Пожалуйста, помогите решить эту проблему с apigateway

Я хочу направить свои запросы с помощью Spring Cloud Gateway в мой облачный кластер Google в кластере. У меня есть 1 микросервис, но он не принимает мои запросы, с которыми я столкнулся.

пожалуйста, помогите решить эту проблему с облачным шлюзом. Нет альтернативных имен субъектов.

#Исключение

javax.net.ssl.SSLHandshakeException: No subject alternative names present
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130) ~[na:na]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
    *__checkpoint ⇢ HTTP GET "/admin/login?objectType=admin&adminId=A002" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130) ~[na:na]
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:378) ~[na:na]
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321) ~[na:na]
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:316) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1318) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1195) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1138) ~[na:na]
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:393) ~[na:na]
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:469) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1273) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1260) ~[na:na]
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1205) ~[na:na]
        at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1559) ~[netty-handler-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1405) ~[netty-handler-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1246) ~[netty-handler-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1295) ~[netty-handler-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) ~[netty-codec-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.91.Final.jar:4.1.91.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.91.Final.jar:4.1.91.Final]
        at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]
Caused by: java.security.cert.CertificateException: No subject alternative names present
    at java.base/sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:138) ~[na:na]
    at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:101) ~[na:na]
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:457) ~[na:na]

приложение.yml

server:
  port: 9999


  ssl:
    enabled: true
    key-alias: ***
    key-store-password: ***
    key-store: classpath:keystore/***.p12
    key-store-type: PKCS12


spring:
  cloud:
    gateway:
      routes:
        - id: ADMIN-SERVICE
          uri: https://google_cloud:8443/v1.0.0/reg
          predicates:
            - Path=/user/**

Я пробовал эти коды, но не работают

static  {
        HttpsURLConnection.setDefaultHostnameVerifier(
                (hostname,sslSession) -> true
        );
}

это решение дает мне chatGpt, но некоторые методы этого решения недоступны в некоторых классах

    @Bean
    public WebClient webClient(GatewayProperties gatewayProperties) throws SSLException {

        SslContext sslContext = SslContextBuilder.forClient()
                .trustManager(InsecureTrustManagerFactory.INSTANCE)
                .build();

        HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);

        WebClient.Builder builder = WebClient.builder().clientConnector(connector);

        if (gatewayProperties != null && gatewayProperties.isUseForwardHeaders()) {
            builder.filter((request, next) -> {
                ServerHttpRequest.Builder mutableReq = request.mutate();
                List<String> forwardedHeaders = gatewayProperties.getForwardedHeaders();
                for (String header : forwardedHeaders) {
                    String value = request.getHeaders().getFirst(header);
                    if (value != null) {
                        mutableReq.header(header, value);
                    }
                }
                return next.exchange(mutableReq.build());
            });
        }

        return builder.build();
    }

Это решение я нашел в stackoverflow, но оно тоже не работает

    @Bean
    public WebClient.Builder getWebClientBuilder() {
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        return WebClient.builder();
    }

Это решение работает с RestTemplate, но не работает в шлюзе Spring Cloud

    @Bean
    public static void disableSslVerification() {
        try
        {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }

            };

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

Я хочу направить свои запросы с помощью локального облачного шлюза spring в мой облачный кластер Google в clutter. У меня есть 1 микросервис, но он не принимает мои запросы.

Я использую Spring boot версии 3 и Spring Cloud Gateway версии 3.

пожалуйста, помогите решить эту проблему с облачным шлюзом -> javax.net.ssl.SSLHandshakeException: нет альтернативных имен субъектов

У меня есть несколько решений, но они не работают, поэтому я публикую эту проблему, пожалуйста, помогите мне и сообществу решить эту проблему.

Спасибо

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
2
0
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваша проблема похожа на вопрос, размещенный здесь: Сертификат для <localhost> не соответствует ни одному из альтернативных имен субъекта Я также предоставил ответ и способ его решения здесь: https://stackoverflow. com/a/53822999/6777695

Вы пытаетесь направить запрос через облачный шлюз Spring в облачный кластер Google, поэтому я предполагаю, что ваше приложение Spring генерирует это исключение. Вам просто нужно убедиться, что сертификат вашего микросервиса имеет правильный список IP и DNS в списке альтернативных имен субъекта. Таким образом, любой, кто пытается вызвать ваш микросервис через https://foo.bar (при условии, что ваш хост доступен на foo.bar), будет возможен только в том случае, если он также присутствует в списке альтернативных имен субъектов вашего сертификата микросервиса. Поэтому обязательно сгенерируйте сертификат, например, с foo.bar в качестве DNS или используйте IP (если вы используете IP) для доступа к вашему микросервису. Вторая ссылка ссылки содержит примеры того, как включить поле SAN при использовании keytool.

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