Search code examples
spring-bootsslspring-securityopensslspring-cloud-gateway

spring cloud gateway problem No subject alternative names present


#Spring Cloud Gateway problem No subject alternative names present

Please Help to solve this problem with apigateway

I want to route my requests using spring cloud gateway to my google cloud cluster in cluter i have 1 microservice but it not accept my requests this problem im facing.

please help to solve this cloud gateway problem No subject alternative names present.

#Exception

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]

application.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/**

I have try this codes but not work

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

this solution give me by chatGpt but this solution some methods are not availble in some classes

    @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();
    }

This solution i found in stackoverflow but that one also not working

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

        return WebClient.builder();
    }

This Solution work with RestTemplate But don't Work in Spring Cloud gateway

    @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();
        }
    }

I want to route my requests using local spring cloud gateway to my google cloud cluster in cluter i have 1 microservice but it not accept my requests.

I'm Using Spring boot version 3 and spring cloud gateway version 3.

please help to solve this cloud gateway problem is -> javax.net.ssl.SSLHandshakeException: No subject alternative names present

I have us Multiple solution but not work so that's why I'm posting this problem please help me and community to solve this problem.

Thank You


Solution

  • Your issue seems to be similar to the question posted here: Certificate for <localhost> doesn't match any of the subject alternative names I also provided an answer and how to resolve it here: https://stackoverflow.com/a/53822999/6777695

    You are trying to route the request via spring cloud gateway to google cloud cluster, so I am assuming your spring application is throwing that exception. You just need to make sure the certificate of your microservice has the correct list of IP and DNS in the subject alternative names list. So anyone who is trying to call your microservice via https://foo.bar (assuming your host is available on foo.bar) would only be possible if that is also present on the subject alternative names list of your certificate of the microservice. So please make sure to generate a certificate having for example foo.bar as DNS or use IP (if you are using an ip) to reach your microservice. The link second link contains examples how to include a SAN field when using keytool.