Multiple application on multiple port not working - Tomcat - tomcat7

I want to host multiple applications on different ports on single instance of tomcat.
I have gone through the following link and made the following changes in my /etc/tomcat/server.xml file and added the following lines.
How to run different apps on single Tomcat instance behind different ports?
Server.xml
<Service name="app1">
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Engine name="Catalina1" defaultHost="localhost">
<Host name="localhost" appBase="app1"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
</Service>
<Service name="app2">
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Engine name="Catalina2" defaultHost="localhost">
<Host name="localhost" appBase="app2"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
</Service>
In the appBase I have provided both the ways.
1. direct folder name.
2. path : webapps/temp.
The problem is when I hit the port 8082 and 8083, I dont get the default page It works for tomcat.
and I am not able to make call to my url.
Eg : ip:8082/temp/xyz/abc/param1=hello&param2=world
ip:8083/temp/xyz/abc/param1=hello&param2=world
When I see in network I am getting 404 error for my url.
But if Call the same url using port 8081 (Default configuration in server.xml) it works perfectly fine I get the response correctly.
What I am doing wrong here.
Also If possible please tell me the drawbacks and problems if I proceed in this way, to host multiple application on single tomcat instance.
Thanks

There are multiple issues with your current configuration. I recommend that you read though the other question you linked to carefully.
Specifically:
Service names must be unique
Engine names must be unique
appBase values must be unique
appBase values must not overlap
Personally, I wouldn't do it this way. I'd run everything under a single service/engine and use virtual hosting. You need to set up a DNS name for each service but with virtual hosting you avoid users having to include the port number in the URL they use to access the service.

Related

Custom spring-based rest API with Apache Knox gateway

I'm trying to do a POC in which I need to protect my cluster through Apache Knox, and my home-grown rest API will sit behind the Knox. How should user authentication work with Knox Ranger, and how will I protect my data access?
Let's start with the service.xml file. It should probably look like the much simpler version below. You would only need the more complex forms if you need to apply specific rules to specific parts of requests or responses. Note that ideally only one route would be required but the ** in Knox means one or more path levels (not zero or more). So without the first route Knox wouldn't send requests to the root /Test_Web_App path to the service.
<service role="TEST_WEB_APP" name="Test_Web_App" version="0.0.1">
<routes>
<route path="/Test_Web_App/?**">
<route path="/Test_Web_App/**?**">
</routes>
</service>
If you wanted to be very specific about it this would be the equivalent. Here the <rewrite apply=""> identifies a specific named rule in rewrite.xml and <rewrite to=""> identifies what part of the request and or response the rule should be applied to.
<service role="TEST_WEB_APP" name="Test_Web_App" version="0.0.1">
<routes>
<route path="/Test_Web_App/?**">
<rewrite apply="TEST_WEB_APP/Test_Web_App" to="request.url"/>
</route>
<route path="/Test_Web_App/**?**">
<rewrite apply="TEST_WEB_APP/Test_Web_App/query" to="request.url"/>
</route>
</routes>
</service>
Now for the rewrite.xml. Yours was pretty close. All I added was a name (i.e. path) resulting in {path=**} to both the pattern and template of the second rule. In the <rule pattern=""> this is used to give a name to the values that are extracted from the matched pattern. In <rewrite template=""> the name is used to populate part of the URL being created with named values extracted from the matched pattern.
<rules>
<rule dir="IN" name="TEST_WEB_APP/Test_Web_App" pattern="*://*:*/**/Test_Web_App/?{**}">
<rewrite template="{$serviceUrl[TEST_WEB_APP]}/?{**}"/>
</rule>
<rule dir="IN" name="TEST_WEB_APP/Test_Web_App/query" pattern="*://*:*/**/Test_Web_App/{path=**}?{**}">
<rewrite template="{$serviceUrl[TEST_WEB_APP]/{path=**}?{**}"/>
</rule>
</rules>
You will need to provide a service definition for your custom REST API to Apache Knox. This will allow Knox to:
Recognize the URLs of the APIs incoming requests to your spring based service and be able to route requests to it
Know how to rewrite specific content such as URLs or other sensitive content from the responses to redirect the client back through gateway when appropriate.
See: http://knox.apache.org/books/knox-0-7-0/dev-guide.html#Service+Definition+Files within the developers guide for how to provide a service definition.
Once a service definition is in place, you just need to add a <service> element within a Knox topology to indicate where the actual spring based service is running. It would be something like this:
<service>
<role>SERVICE</role>
<url>http://url.to.your.service/v1/...</url>
</service>
This is also described in the same section of the developers guide.
You may also find the users guide helpful for additional examples of service declarations within the topology.
You can look at those examples and compare them to the service definition files for those existing services to see how service roles map. This will help you do the same for your own service.
For authentication details, see http://knox.apache.org/books/knox-0-7-0/user-guide.html#Authentication within the users guide for instructions in setting up LDAP based authentication. There are other authentication and federation provider implementations that may be of interest to you as well. You can find them within the users guide too.
Feel free to engage the dev or user email lists for Apache Knox as well.
These are my 2 xml file please look in to it if i have mad any mistake or what else i need to do
**rewrite.xml
<rule dir="IN" name="TEST_WEB_APP/Test_Web_App" pattern="*://*:*/**/Test_Web_App/?{**}">
<rewrite template="{$serviceUrl[TEST_WEB_APP]}/?{**}"/>
</rule>
<rule dir="IN" name="TEST_WEB_APP/Test_Web_App/query" pattern="*://*:*/**/Test_Web_App/{**}?{**}">
<rewrite template="{$serviceUrl[TEST_WEB_APP]/{**}?{**}"/>
</rule>
</rules>
**service.xml
<service role="TEST_WEB_APP" name="Test_Web_App" version="0.0.1">
<routes>
<route path="/Test_Web_App/**">
<rewrite apply="TEST_WEB_APP/Test_Web_App/**" to="response.body" />
</route>
<route path="/Test_Web_App/**?**">
<rewrite apply="TEST_WEB_APP/Test_Web_App/**?**" to="response.body"/>
</routes>
</service>

Page displaying '?', instead of 'é'

I am retriving data from oracle11g and displaying the data on IE8 and IE9 browser, but the couldn't display some special characters (eg. é)
In my webpage, I have explicitly declare 'UTF-8' encoding.
For my tomcat webserver, the server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true"/>
I read some other questions in stackflow, they mentioned to also ensure the database connection is using 'UTF-8' too.
<Resource name="jdbc/AppDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="20" maxIdle="10" maxWait="10000"
username="foo"
password="bar"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/ ID_development?useEncoding=true&characterEncoding=UTF-8"
/>
The solution given is for mysql.
How can i set the encoding if im using oracleDriver?
<Resource name="jdbc/AppDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:#127.0.0.1:1521:ora11"
username="foo"
password="bar"
maxActive="20"
maxIdle="1000"
maxWait="-1" />
Please review this answer. Regardless of fact that it's focused on SQL Developer, it contains information about tuning JDBC driver and points out how to properly handle unicode character types in Oracle.
Update
Troubles with displaying characters on the client may be caused by wrong NLS_LANG settings on the database client (Tomcat in your case). For thin JDBC driver NLS_LANG value derived from java locale settings.
For possible variants you can look through the answers on this question and check Oracle documentation.
If a real source of the problem lies to character set of Oracle database connection, then there are only two possible end points to check: NLS_LANG and oracle.jdbc.defaultNChar . So you need to examine if both set properly to figure out what is happened.

ADO.NET EF - can't establish DB connection using VS2010

I'm following this tutorial : http://msdn.microsoft.com/en-us/data/jj193542 for Code First basics using ADO.NET EF. The problem is that when executing the code the DataBase is not created automatically and I think that this is because the configurations in my app.config but it's my first day with real code and I can't figure out how to adjust my config file so I can connect to my server and use a created DataBase if neccessary or let the program from the tutorial create new database as expected from what is written.
This is my App.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<!-- <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory> -->
<connectionStrings>
<add name="BloggingContext"
providerName="System.Data.SqlClient"
connectionString="server=milka-pc\sqlserver2012;Database=Panorama;user id=MyID;password=MyPass;port=3333;Integrated Security=True;"/>
</connectionStrings>
<!--<contexts>
<context type=" Blogging.BloggingContext, MyAssembly">
<databaseInitializer type="Blogging.MyCustomBlogInitializer, MyAssembly" />
</context>
</contexts>-->
</entityFramework>
</configuration>
As you can see some parts are commented as I tried a various things to make it work.
This is how y server explorer looks like while I'm trying to connect:
Also since I have zero experience with ViasualStudioXXXX and connecting to DataBases this is what I see and how I select my server:
There in milka-pc\sqlserver2012 I have a DB named Panorama which I can use or better follow the tutorial step by step and leave the program to create my new DB. For now I can't neither of these two. And to connect to milka-pc\sqlserver2012 I need to provied UserName and Password which I did in App.config. I say this just to know that these fields are not blank
If you are sure that milka-pc\sqlserver2012 is in fact working on port 3333 as you suggested
change your connectionstring to this:
<add name="BloggingContext"
providerName="System.Data.SqlClient"
connectionString="server=milka-pc\sqlserver2012,3333;Database=Panorama;user id=MyID;password=MyPass;Integrated Security=True;"/>
Just to make sure try that connection string in you SQL management studio with provided credentials.
If that doesnt work consult your sql server configuration manager, specifically under SQL server Network configuration make sure that your instance has enabled TCP/IP pipe with appropriate port enabled.
Cheers.

HTTPS login with Spring Security redirects to HTTP

I have a Spring web app, secured with Spring Security, running on EC2. In front of the EC2 instance is an Elastic Load Balancer with an SSL cert (https terminates at the load balancer ie. port 443 -> port 80), so from Tomcat's perspective, inbound requests are HTTP.
My login form submits to https, however the subsequent redirect goes to http (success or fail). The authentication was successful, and I can go back to https and I'm logged in.
My login configuration looks like so:
<security:form-login
default-target-url="/home"
login-page="/"
login-processing-url="/processlogin"
authentication-failure-url="/?login_error=1"/>
What do I need to change to make default-target-url and authentication-failure-url go to https?
Tomcat 6
Spring Security 3.0.x
Your spring configuration should be agnostic to the used protocol. If you use something like "requires-channel", you'll run into problems sooner or later, especially if you want to deploy the same application to a development environment without https.
Instead, consider to configure your tomcat properly. You can do this with RemoteIpValve. Depending on which headers the loadbalancer sends, your server.xml configuration needs to contain something like this:
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
internalProxies=".*"
protocolHeader="X-Forwarded-Proto"
httpsServerPort="443"
/>
Spring will determine the absolute redirect address based on the ServletRequest, so change the httpsServerPort if you are using something else than 443:
The httpsServerPort is the port returned by
ServletRequest.getServerPort() when the protocolHeader indicates https
protocol
If it is a Spring Boot application (I use currently the 2.0.0 release), the following configuration within the application.properties file should be enough:
server.tomcat.protocol-header=x-forwarded-proto
This worked for me on AWS with an load balancer at the front.
For Spring Boot < 2.0.0 it should also work (not tested)
I had the same problem with Spring Boot behind Google Kubernetes. Adding these two lines to application.properties did it for me
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
Source: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https
Solution was two fold
(1) application.yml
server:
use-forward-headers: true
(2) in servers /etc/apache2/sites-enabled/oow.com-le-ssl.conf
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
(2.1) and enabled the apache module with
sudo a2enmod headers
Put it together with the help of this and this
One way I got this working is by adding the following config
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
<form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
<logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
...
</http>
Had to add always-use-default-target="true" and default-target-url="https://....". Not the ideal way as you need to hard code the url in the config.
I set requires-channel="any" on all intercept-urls. This allows it to still work in my dev environment where I don't use SSL.
<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
Then, create an apache virtual host that redirects all traffic to the HTTPS version.
<VirtualHost *:80>
ServerName www.mywebsite.com
Redirect permanent / https://www.mywebsite.com/
</VirtualHost>
I am also facing exactly same problem and till the time I get proper solution I am redirecting my requests from proxy server to tomcat server over AJP instead of HTTP.
Below is my apache configuration
ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject
use below lines of code in web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Login and Restricted Space URLs</web-resource-name>
<url-pattern>/j_security_check</url-pattern>
<url-pattern>/loginpage.rose</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
it makes forced to use HTTPS.
In my case, I had to REMOVE the property server.use-forward-headers=true.
This is my setup:
Digital Ocean LB --> Kubernetes cluster with Ingress --> Spring boot Application
Tried everything mentioned above for my k8's to spring boot application, problem was k8 was secured and ssl was handled by SSL accelerator sitting in front of ingress. The application only received http requests and spring security also forwarded to http, which was never found. The solution that worked for me:
nginx.ingress.kubernetes.io/proxy-redirect-from: http://$http_host/
nginx.ingress.kubernetes.io/proxy-redirect-to: https://$http_host/$namespace/helloworld-service/

Publishing a WCF Server and client and their endpoints

Imagine developing a WCF solution with two projects (WCF Service/ and web application as WCF Client). As long as I'm developing these two projects in visual studio and referencing service to client (Web Application) as server reference there is no problem. Visual studio automatically assign a port for WCF server and configure all needed configuration including Server And Client binging to something like this in server:
<service behaviorConfiguration="DefaultServiceBehavior"
name="MYWCFProject.MyService">
<endpoint address="" binding="wsHttpBinding" contract="MYWCFProject.IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/MyService.svc" />
</baseAddresses>
</host>
</service>
and in client:
<client>
<endpoint address="http://localhost:8731/MyService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService"
contract="MyWCFProject.IMyService"
name="WSHttpBinding_IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
The problem is I want to frequently publish this two project in two different servers as my production servers and Service url will be "http://mywcfdomain/MyService.svc". I don't want to change config file every time I publish my server project.
The question is: is there any feature in Visual Studio 2008 to automatically change the URLs or I have to define two different endpoints and I set them within my code (based on a parameter in my configuration for example Development/Published).
Check the answer i posted here for a similar question (how to set client endpoints programmatically).
The other way to do it and keep it totally declarative is to write an installer for your app, and have the installer update the config files. This solution would be a bit more pure, but harder to implement, and exactly how it is done would depend on which installer you use.

Resources