This is a personal study notes of Apache Tomcat. Below are main reference material.
- YouTube Apache Tomcat Full Tutorial,owed by Alpha Brains Courses. https://www.youtube.com/watch?v=rElJIPRw5iM&t=801s
1、Overview
2、Quick Enable HTTPS In Tomcat
Enabling HTTPS In Tomcat requires two major pieces.
- We need a
DC
. In development environment, a ‘self-signed’DC
is enough, although it’s inadequate for production. - We need to configure Tomcat so that it can locate our self-signed
DC
.
Here’s the steps.
- Creating a self-signed
DC
: Core Java ships with a utility calledkeytool
that can be used to generate aDC
.
It has various of options. I just show the most simple but useful example.
keytool -genkeypair -keyalg RSA -keystore myDC.keystore
-genkeypair
: means generate a key pair.-genkey
is the eariier version of-genkeypair
. They function samely.
This operation is interactive, it’ll ask you fill your personal information, like name, organization .e.t.c.-keyalg RSA
: means using RSA encryption algorithme.-keystore myDC.keystore
: It’s not necessary but highly commended. It’s used to rename theDC
. A proper name helps a lot. The format of the name should be*.keystore
After fill password and some personal infomation it generate a file named myDC.keystore
- Configure Tomcat so that it can find the
DC
fromstep1
. Go toTOMCAT_HOME/conf/server.xml
in the roughy middle.
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
-->
Uncomment this fraction and add some attributes. I also break out each attributes on a single line for readability.
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="${user.home}/Desktop/myDC.keystore"
keystorePass="123456"
/>
clientAuth="false"
: Means only browsers challenge the server but the server doesn’t challenge the browsers. The browsers don’t need provide aDC
to connenct the server.
If you wan’t to make the server service exclusive, then set it true.
- Restart the Tomcat and access
https://localhost:8443
.
Since you use want to have a secure connection but theDC
the server providing is self-signed, which means that no company with credibility voucher for thisDC
. You’ll get warnings from your browser that this connection is not safe.
But you can still insist accessing by"Proceed to localhost (unsafe)"
2.1、Further Details
2.1.1、Format Of DC
We generate a DC with keytool
utility from scratch in below contents. Actually the DC is in format of JKS
. Tomcat support various formats.
q
JKS
: abbreviation of Java Key Store. So it’s speciic for Java.PKCS and PKCS12
: abbreviation of Public Key Cryptography Standards.
You can have tools from OpenSSL(https://www.openssl.org) to generateDC
inPKCS
orPKCS12
format.
keytool
can also importPKCS12
into its keystore.
2.1.2、Attributes Of Connector
In configuring Tomcat, we uncomment <connector/>
element to enable HTTPS
. Here is going to explore the details of its attributes.
protocol
: We need to a introduce a bigger picture. TheSSL
for the “S” inHTTPS
has two way available in Tomcat.JSSE
: Java Secure Socket Extention, introduced since jdk 1.4. It’s a fine in development but not recommended for production.APR
: Apache Portable Runtime, recommended for production.
Back to attribute protocol
. It has 5 options like below.
Value | Comment |
---|---|
HTTP/1.1 | Let Tomcat choose, not reliable not recommended |
org.apache.coyote.http11.Http11Protocol | JSSE BIO (Blocking I/O) impelementation, just ok for development but not for production since NIO is better than Blocking IO |
org.apache.coyote.http11.Http11NioProtocol | JSSE NIO (New I/O) implementation |
org.apache.coyote.http11.Http11Nio2Protocol | JSSE NIO2 implementation |
org.apache.coyote.http11.Http11AprProtocol | APR with OpenSSL implementation (‘keep-alive’ automatic), highly recommended |
3、User Authentication And Authorization
3.1、What Is Authentication And Authorization
User authentication
is identitying a user, often with username and password.User authorization
is how much access the user have after authentication.
We can do the two things with massive code, which is a heavy lift.
Fortunately, we use Tomcat’s module called Container-Managed
to implement user authentication/authorization.
Tomcat provides various options, including turning over auth/auth to a LDAP or similar service.
The only challenge for developer is to provide identity and credential in exactly the way the contaiiner expects.
HTTP authentication/authorization basically has four modes, or we can say it has four ways to implement auth/auth.
- basic: browser provides login form, username and password sent as is.
- digest: It’s very like the basic but it sent a digest of password not the password itself. It not used much.
- form: App rather than browser provides the login view and the container handles the auth/auth. It’s preferred method.
- client-cert: The client sends its digital certificate that vouchser for its identity rather than username and password.
3.2、Realms
Let me introduce some notions .
-
realm
in Tomcat is a database that used to store user indentities (e.g., username), crednetials (e.g., password) and security roles.
Arealm
is created and configured inTOMCAT_HOME/conf/server.xml
. -
JNDI
: Java Naming and Directory Interface. An API for associating name with resources within a prescribed syntax. Example is requesting for a group of data stored in database.
Sample name:https://postgresql://localhost:5432/userRoles
.
In Tomcat, we have below built-in realms to use.
They differ from two aspects. one is access like through a JDBC driver to get info or through a JNDI provider or through local file system.
The other one is in where data is stored. Auth/auth info might be stored in a database, a xml or a LDAP-based server.
- JDBCRealm: auth/auth info is stored in a relational database, and access through a JDBC driver.
- DataSourceRealm: auth/auth info is stored in a relational database, and access through a JNDI.
- JNDIRealm: auth/auth info is stored in a LDAP-based directory server, accessed through a JNDI provider.
- UserDatabaseRealm: auth/auth info is stored in a UserDatabase JNDI resource, which is typically stored in a XML file on the local file system, with
TOMCAT/conf/tomcat-users.xml
as the defauly. This realm is well-suited in development.- UserLockoutRealm: a subtype of UserDatabaseRealm to prevent brute-force attacks that guess password (directory attack).
- MemoryRealm: In effect, an earlier version of UserDatabaseRealm but without JNDI-based lookups.
- JAASRealm: auth/auth access through JAAS (Java Authentication and Authorization Service) framework. with complete flexibility in how to persist info. Used in Java service.
Here is an example of JDBCRealm. You can see the details like connection info, tables. The <Realm>
element is configured in TOMCAT_HOME/config/server.xml
.
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority?user=dbuser&password=dbpass"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
3.3、Code Example
I’m going to show how to use realm to implment authentication and authorization.
It’s not the only way to implement auth/auth. Things are usually more tricky in production.
It’s the most simple one. I store role, user info in local .xml files while in production they are often stored in a thrid party service. However, no matter where they are stored and how to get them, we just need to have a general idea how Realms work in auth/auth.
Anyway Three brief steps are required.
- Specify which
Realm
to use. This step is in effect to confirm in where the user info stored and how to get user info. This configure is usually - Restrict which roles are allowed to access this web app.
- Configure other elements. For example, if you choose
UserDatabaseRealm
, it means that user can submit a form containing username and password or certificate to login. So you need to configure some elements and tell Tomcat which .jsp is the login page and so on.
3.3.1、Choose A Realm
Tomcat uses UserDatabaseRealm
by default, which means that in this case we don’t need to configure extra elements in TOMCAT_HOME/conf/server.xml
, since UserDatabaseRealm
get user info form TOMCAT_HOME/conf/tomcat-users
and we just add a user moe
.
Here is the default configuration
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
3.3.2、Restrict Access Role
The first step is to configure web.xml
. We need to tell Tomcat below things.
- role: Tell Tocmat which role the users need to be are allowed to access this web app. In this case only if the role of use is
bigshot
then it can access this web app. - login page: Tell Tomcat that it should direct to which page if the user hasn’t logged in.
- error page: Tell Tomcat that it should direct to which page if the user fails to log in.
<?xml version = "1.0" encoding = "UTF-8"?>
<web-app>
<!-- Added to ensure HTTPS for the app -->
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<!-- authorization constraint: required role -->
<auth-constraint>
<role-name>bigshot</role-name>
</auth-constraint>
<!-- transport-level constraint: secure channel -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
<user-data-constraint>
<transport-guarantee>INTEGRAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
<welcome-file-list>
<welcome-file>securePage1.jsp</welcome-file>
</welcome-file-list>
</web-app>
3.3.3、Add Users
We can add a user in TOMCAT_HOME/conf/tomcat-users.xml
, specifying its username, password and role.
<tomcat-users>
<role rolename="bigshot"/>
<user username="moe" password="moe" roles="bigshot"/>
</tomcat-users>
3.3.4、Result
- Before login, Tomcat show login page compulsarily.
- I try to login with error username or error password. Tomcat can’t find registered user in
tomcat-users.xml
, so it insists me loging in again and again. - Finally I enter right username and password, it shows welcome page.