How do I fix bad request this combination of host and port requires TLS?

calendar_today

Updated On:

Products

ESP Workload Automation

Issue/Introduction

We have started with ESP REST API STC with TLS configured. When access it thru web browser with HTTPS, we got error:
Bad Request This combination of host and port requires TLS.

Cause

There are two possible causes:
#1 Sometimes even you enter HTTPS on web browser, it may still be resolved to HTTP. #2  If you want REST server to actually do the encryption. But if there is also AT-TLS rule for the same port, AT-TLS will encrypt already encrypted communication. 

Environment

Release : 12.0

Component : CA ESP WORKLOAD AUTOMATION

Resolution

Solutions:
#1 Make sure HTTPS is used.

#2 Check if AT-TLS is set on MVS system; if yes, then the ESP REST API port should be excluded.

Feedback

thumb_up Yes

thumb_down No

You are here

Problem Description:

If you are trying to log into TIBCO JasperReports® Server via SSL and you believe you have configured the connector port in Tomcat correctly, but you are getting this error from any browser. Bad Request This combination of host and port requires TLS


Solution:

Check your URL. Most likely you have left out the s in https. For example,

http://localhost:8443/jasperserver-pro/login.html 

Correct URL is:

https://localhost:8443/jasperserver-pro/login.html

  • Log in or register to post comments

Describe the bug
I am using spring-cloud-gcp-starter with custom domain + custom certificate(not google managed).
Although the configuration in app.yaml works fine but at the backend the redirection doesn't work as intended as I am seeing the error:-
Bad Request This combination of host and port requires TLS. on a HTTPS connection.
This is my app.yaml

runtime: java11
instance_class: F2
handlers:
  - url: /.*
    script: auto
    secure: always
    redirect_http_response_code: 301

And the related application.properties

server.ssl.enabled=true
server.ssl.protocol=TLS
server.port=${PORT:8080}
server.ssl.client-auth=none
server.ssl.key-store=classpath:data/someKeystore.p12
server.ssl.key-store-password=somePassword
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=something
server.ssl.key-password=anotherpassword

Sample
I have tested the app locally, for some reason the redirection on localhost doesn't work at all but if I add https the request processes without the 'Bad Request' error.
To reproduce: Get a Cert from CA> Add it to GAE> Use the same cert to Configure Spring boot server for SSL> Deploy the app> See the error.

@Guneetgstar What is the purpose of the Spring Cloud GCP starter in your app? Does everything work without it? Since you're running on App Engine, it should manage SSL for you. I don't think you even need to configure your Spring Boot app for it. Have you tried following these instructions: https://cloud.google.com/load-balancing/docs/ssl-certificates/self-managed-certs?

-1 I am using Cloud SQL as well so I need the spring-cloud-gcp-starter for auto-configuration.
-2 I haven't tested everything without it but this configuration should work as well.
-3 So App engine is definitely managing the SSL for me but what I have seen is that App Engine is still communicating with my Tomcat container over HTTP as I get the following response with HATEOAS:

{
"_embedded" : .....
"_links" : {
    "self" : {
      "href" : "http://api.example.in/api/products"
    },
    "profile" : {
      "href" : "http://api.example.in/api/profile/products"
    },
    "search" : {
      "href" : "http://api.example.in/api/products/search"
    }
  },
"page" : ....
}

So I thought I should just enable SSL in my spring boot application and send redirects for every http request to https manually(not though app engine)(also tried removing handlers but that was another strange behaviour)(I think of removing the self-managed certs at all from app engine and also disabling google managed certs and then enable my https server but that also doesn't seem to be possible as i can't disable both at the same time).
-4 Yes I have read the instructions and they certainly helped me setting up self-managed SSL certificates for this app.

I believe App Engine basically assumes that your application is accessible via HTTP, and App Engine adds a layer of security with SSL that you can customize. In any case, this seems more like a question about App Engine rather than Spring or this project in particular.

@meltsufin So just for you I debugged it further and here I have enough evidence to say that this is a spring-gcp-cloud related issue.
I tested it on another app which doesn't use spring at all and logged HttpServletRequest.getScheme() and I got this:

How do I fix bad request this combination of host and port requires TLS?

Where as the same log on an spring-gcp application gives this:
How do I fix bad request this combination of host and port requires TLS?

Dif:

  • Non-Spring app doesn't have custom SSL configured which doesn't matter here because in both cases I am using *.appspot.com domains which definitely use Google certs.
  • Non-Spring app uses java8 where as spring app has java11

Similarity:
Both requests were made using curl https://---url---

Expected:
Even if its something configuration related, the default behaviour should be same in both cases.

You may just be observing differences between App Engine Java 11 and Java 8 in how they propagate HTTP scheme attribute to HttpServletRequest. It looks like for Java 11, propagation doesn't happen. Either way, the request is over https between user and App Engine. Try deploying the non-Spring app to Java 11 runtime. In any case, if you want to ensure that your users are redirected to https, use this App Engine configuration:

handlers:
- url: /.*
  script: auto
  secure: always
  redirect_http_response_code: 301

See: https://cloud.google.com/appengine/docs/standard/java11/application-security

If you read my issue you will see exactly these 5 lines already in my code.

handlers:
- url: /.*
  script: auto
  secure: always
  redirect_http_response_code: 301

Anyways, as you said I tested it again and you are right, the issue is with the propagation, in app engine java 11 runtime the scheme is always http. What do you think, shouldn't it be treated as a bug? After all I will be appending this with the response given to the user it can make him loose trust as he doesn't know that 'Either way, the request is over https between user and App Engine' until I don't mess up with spring-data-rest to change how it generates the response which I have idea I can. Should I open an issue for this with the respective repository?

It looks like a bug to me. If anything, it's at least a documentation bug, since I don't see this difference mentioned anywhere in the App Engine Java 8 and 11 runtimes docs.
You can file the bug here.
Please link to the issue here, once filed. Many thanks!

Yeah this seems to me too as I have messed a whole day to find/fix this small requisite with no success and spent more time testing alternatives. What made me think that its rather a spring-cloud-gcp related issue is that I didn't find a single issue regarding this with GAE and its been here for years whereas spring-cloud-gcp has less users as compared to GAE itself which makes one not to expect a bug from GAE at least.

I have filed a bug on the link you given to issuetacker. I guess you can finally close it now.

@Guneetgstar This is a great example of a very valuable community contribution! Hopefully, others will find this thread when they encounter the same problem before it's fixed, and won't have to spend time on it like you did. Thanks again!

What does requires TLS mean?

Transport Layer Security (TLS) is a security protocol that encrypts email for privacy. TLS prevents unauthorized access of your email when it's in transit over internet connections.

Does HTTP support TLS?

The only difference between the two protocols is that HTTPS uses TLS (SSL) to encrypt normal HTTP requests and responses, and to digitally sign those requests and responses. As a result, HTTPS is far more secure than HTTP. A website that uses HTTP has http:// in its URL, while a website that uses HTTPS has https://.

How does HTTP over TLS work?

An SSL or TLS certificate works by storing your randomly generated keys (public and private) in your server. The public key is verified with the client and the private key used in the decryption process. HTTP is just a protocol, but when paired with TLS or transport layer security it becomes encrypted.