404 Not Found : after adding https to spring boot - spring-boot

In my spring boot application I added ssl properties in application.yml as below:
server:
ssl:
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: PKCS12
key-alias: alias
enabled: true
port: 443
and the application war file has successfully deployed on tomcat server.Configured server.xml of tomcat as below for https:
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true"
keystoreFile="conf/keystore.p12" keystorePass="password" keyAlias="alias" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.1"/>
But when I try to call the url(https://fortunenetworks.in:443/ourectestschool/public/users/checkToken) from postman I got below error:
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body>
</html>
If I tried the same url with http(http://fortunenetworks.in:443/ourectestschool/public/users/checkToken) got below msg:
<html>
<head>
<title>400 Bad Request</title>
</head>
<body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
<p>Additionally, a 400 Bad Request
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body>
</html>
When I use http and 8080 as port(http://fortunenetworks.in:8080/ourectestschool/public/users/checkToken) the url is working.
My controller class is:
#RestController
#RequestMapping("/public/users")
public class PublicController {
#RequestMapping(value = "/checkToken",method = RequestMethod.GET)
public #ResponseBody
String getCheckToken() {
return "Success";
}
}
Why is my https call is not working,what i am doing wrong here.

and the application war file has successfully deployed on tomcat
server.Configured server.xml of tomcat as below for https:
Considering that you have a spring boot application deployed as war file in some existing external tomcat server, you don't need to configure the spring-boot properties for ssl.
So the properies defined for the above reason inside application.yml can be removed
You only need to configure your server.xml on your external tomcat you have running for ssl to work.
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true"
keystoreFile="conf/keystore.p12" keystorePass="password" keyAlias="alias" clientAuth="false" sslProtocol="TLS"> sslEnabledProtocols="TLSv1.2,TLSv1.1"/>
Make sure that everything you have configured in the above snippet is complying (certificate, keystorePass..)
Also any modification of server.xml requires tomcat restart for changes to apply.
You can use this as a simple example tutorial.
Then the https://fortunenetworks.in:443/ourectestschool/public/users/checkToken should become reachable.

Related

How to configure tomcat for https when you already setup https in application level

There are thousands of articles on how to set up HTTPS in either tomcat or at the application level in your spring boot application. But I didn't find a way to configure tomcat for an application that already has configured HTTPS.
I've already set up my spring boot application to run on HTTPS by configuring these properties:
server.port=7070
server.ssl.enabled=true
server.ssl.key-store-password=my_password
server.ssl.key-store-type=PKCS12
server.ssl.key-store=keystore-path
server.ssl.key-alias=key_alias
And it perfectly works when I run my IDE(Intellij) and serves on https://localhost:7070 on my machine.
On the other hand, When I deploy my app into the tomcat. it runs on the port of tomcat which is defined on server.xml connector. for instance :
<Connector port="7071" protocol="HTTP/1.1" connectionTimeout="20000" />
By doing so, The connector port in tomcat overrides the port number on the application.properties.
So if I want to run my application in HTTPS in tomcat, Documents says I need to define a new connector, for example :
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
or
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
But these ways, I have to configure my Keystore, password, alias, and ... again in my tomcat.
I'm wondering is there any other way around not configuring again my Keystore, password and .. again in tomcat?
No, there is no other way around it. server.* properties are only applied when running the application in an embedded container. When deploying to an existing Tomcat instance, they are not used.

ReDirect Tomcat 9 and IIS with direct URL

The setup is on a windows server 2019:
Tomcat 9.0.38, test application is up an running
Part of my server.xml config file:
<Connector
address="x.x.x.x"
port="8000"
URIEncoding="UTF-8"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443"
compression="on"
compressionMinSize="1024"
noCompressionUserAgents="gozilla, traviata"
compressibleMimeType="text/html,text/xml,text/css,text/plain,text/javascript, image/jpeg"
server="Tomcat"/>
<Connector
protocol="AJP/1.3"
address="x.x.x.x"
port="8009"
redirectPort="8443"
tomcatAuthentication="false"
secretRequired="false"
packetSize="65536" />
IIS is als working fine
Add Virtual Directory...
-> Jakarta
Connector is also configured (isapi_redirect.dll)
worker.list=local
worker.local.type=ajp13
worker.local.host=x.x.x.x
worker.local.port=8009
worker.local.max_packet_size=65536
/test/*=local
/test=local
Now I am able to access the application via the "url/test" but i want to access the application only by the "url".
How can i do this?
I mean, right now i am able to access the application by:
http://blabla.loc/test
but I want to access the application only by:
http://blabla.loc
What does url/test mean? shouldn’t test be part of the url, or is your url referring to the hostname? if so, you can try to use url rewrite.
More information about url rewrite you can refer to this link: url rewrite.
If you have difficulty creating url rule, then you can explain your needs in detail, and I can write a demo for you.
Try this rule:
<rule name="test" stopProcessing="true">
<match url="^test$" />
<action type="Redirect" url="http://{HTTP_HOST}" />
</rule>
My solution is probably not the best, but is working
I changed the folder / application from test to root and now i am able to access the application directly

Clarification in configuring OCSP in tomcat

We can configure OCSP in tomcat using,
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11AprProtocol"
secure="true" scheme="https"
SSLEnabled="true" SSLCertificateFile="/path/to/ocsp-cert.crt"
SSLCertificateKeyFile="/path/to/ocsp-cert.key"
SSLCACertificateFile="/path/to/ca.pem"
SSLVerifyClient="require"
SSLVerifyDepth="10"
clientAuth="true"/>
As mentioned in tomcat documentation, https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Using_OCSP_Certificates
But from that documentation I didn't get where OCSP is performed whether on server side(For revocating client certificate) or client side(for revocating server certificate) ?

Configuring Liberty with httpProxyRedirect

I am attempting to redirect traffic on insecure port to secure port as described here:
https://www.ibm.com/support/knowledgecenter/en/SSD28V_9.0.0/com.ibm.websphere.liberty.autogen.core.doc/ae/rwlp_config_httpProxyRedirect.html
Instead both ports are available and I see nothing in the logs. It's as if the httpProxyRedirect isn't being configured at all.
<?xml version="1.0" encoding="UTF-8"?>
<server description="CAST Liberty Server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
</featureManager>
<application id="app" context-root="/" type="war" location="${war.name}">
<classloader apiTypeVisibility="spec, ibm-api, api, third-party" />
</application>
<httpProxyRedirect id="defaultHttpProxyRedirect" httpPort="${http.port}" httpsPort="${https.port}" />
<keyStore id="defaultKeyStore" password="pass" />
<httpEndpoint host="*" httpPort="${http.port}" httpsPort="${https.port}" id="defaultHttpEndpoint" />
<applicationMonitor updateTrigger="mbean" />
</server>
Most likely, you are missing the security-constraints in the web.xml. This configuration tells the server which URLs need to be accessed over a secure transport and then re-directs qualifying requests from the non-secure port to the secure port. This tutorial may help: https://docs.oracle.com/cd/E19798-01/821-1841/bncbk/index.html
Also, keep in mind that the httpProxyRedirect configuration in the server.xml is intended for redirecting when you have a proxy server in front of your application server. For example, you may have your proxy server on the main "www.ibm.com" host - listening on HTTP port 80 and HTTPS port 443. But that host may route some requests to your Liberty application server on some other host (like "app1host.internal.ibm.com") that listens on different ports (i.e. HTTP port 9080 and HTTPS port 9443). In that case, just using the security-constraints in the web.xml would attempt to redirect the client request on the Liberty server from 9080 to 9443 but on the www.ibm.com host - where nothing is listening on those ports. In this case, you should configure httpProxyRedirect like this:
<httpProxyRedirect httpPort="80" httpsPort="443" host="www.ibm.com" />
With the configuration, a client HTTP request to a secured URL will get redirected to www.ibm.com on port 443, where the proxy server will forward the request to app1host.internal.ibm.com port 9443.
Hope this helps,
Andy
This is the security constraint that i am using in my web.xml and it works well for both Tomcat and IBM Websphere 8.5.5.15:
<security-constraint>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Note: make sure that you put it after your <servlet-mapping>.

mod_jk utf-8 character set setup

I am running httpd + mod_jk + 2 tomcat servers in Ubuntu. When I submit a form in a non-Latin language I get garbage in the DB.
If I submit the same form through Tomcat directly bypassing httpd everything looks good.
following is my configuration:
/etc/apache2/conf.d/charset:
AddDefaultCharset UTF-8
tomcat1:
< Connector port="8080" protocol="AJP/1.3" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
tomcat2:
< Connector port="9080" protocol="AJP/1.3" connectionTimeout="20000" redirectPort="9443" URIEncoding="UTF-8" />
JDBC connection:
jdbc:mysql://localhost:3306/myapp?useEncoding=true&characterEncoding=UTF-8
/etc/apache2/mods-available/jk.conf (the same file I set up my loadbalancer)
JkOptions +ForwardURICompatUnparsed
Am I missing something?
Thank You!
I found my problem, I mixed up the HTTP connector with the AJP connector which was declared twice in Tomcat's server.xml . The second declaration did not even include the attribute URIEncoding.
<Connector URIEncoding="UTF-8" port="8009" protocol="AJP/1.3" connectionTimeout="10000" keepAliveTimeout="10000" redirectPort="8443"/>
work fine for me

Resources