SSO with Apache Tomcat – 用Apache Tomcat进行SSO

最后修改: 2022年 3月 22日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’ll learn about the Tomcat server fundamentals, how it works, and how to enable Tomcat’s Single Sign-On (SSO) feature. We’ll explore the Tomcat server and the web app’s required configurations.

在本文中,我们将了解Tomcat服务器的基本原理,它是如何工作的,以及如何启用Tomcat的单点登录(SSO)功能。我们将探讨Tomcat服务器和Web应用的必要配置。

2. Tomcat Architecture

2.Tomcat架构

The main pieces that compose the Catalina servlet container are the server that contains services that will define connectors and an engine built of hosts, and finally, these hosts will contain contexts or web apps.

构成Catalina servlet容器的主要部分是包含定义连接器的服务的服务器和由主机构建的引擎,最后,这些主机将包含上下文或网络应用。

Connectors listen to the client’s requests and send back the responses. In Tomcat 10, we can find connectors to the following protocols: HTTP/1.1, HTTP/2, and AJP.

连接器监听客户端的请求,并将响应送回。在Tomcat 10中,我们可以找到以下协议的连接器。HTTP/1.1HTTP/2,和AJP

The engine will process the requests received by the connectors and produce the output. It will contain a processing pipeline, which is a chain of processes that will be executed per request to produce the response. These processes are the Tomcat’s valves. For instance, the SSO on Tomcat is implemented as a valve.

该引擎将处理连接器收到的请求并产生输出。它将包含一个处理管道,这是一个进程链,每个请求将被执行以产生响应。这些进程就是Tomcat的。例如,Tomcat上的SSO被实现为一个阀。

After that, we find hosts that will define virtual hosts that associate a network name with a server. This is the level where the SSO valve will be defined, so all the contexts of the host will be under the SSO.

之后,我们找到主机,它将定义虚拟主机,将网络名称与服务器联系起来。这是定义SSO阀的级别,因此主机的所有上下文都将在SSO之下。

And finally, we’ll have contexts elements associated with hosts. These contexts are the web applications that will run on the server. The contexts must follow the servlet specification 2.3 or later.

最后,我们将有与主机相关的上下文元素。这些上下文是将在服务器上运行的Web应用程序。这些上下文必须遵循Servlet规范2.3或更高版本。

3. Single Sign-On on Tomcat

3.Tomcat上的单点登录

Tomcat implements the Single Sign-On feature in a valve that must be configured at the host level. The way it works is that the SSO valve will store the user credentials and will pass them when required, so the user won’t need to log in again.

Tomcat在一个必须在主机级配置的阀门中实现了单点登录功能。它的工作方式是,SSO阀将存储用户凭证,并在需要时将其传递,因此用户不需要再次登录。

The SSO valve needs that the following requirements are met:

SSO阀门需要满足以下要求

  • The Realm or the “users database” must be shared by all the web apps under the virtual host.
  • Web apps authentication mechanism must be one of the standard authenticators: Basic, Digest, Form, SSL, or SPNEGO.
  • When a client requests a protected resource, the server will execute the authentication mechanism of the web app.
  • The server will use the roles of the authenticated user to access protected resources of the web apps under the virtual host without login in again.
  • When the user logs out of a web app, the server will invalidate the user session in all the web apps.
  • The client must accept cookies. The cookies store the token that associates the requests with the user credentials.

3.1. Tomcat Server Configurations

3.1.Tomcat服务器配置

On the server-side, we need to configure the SingleSignOn valve and the Realm or “user database”. These configurations are inside the server.xml file under the conf folder of Tomcat’s installation. To add the SSO valve, we need to uncomment the following line:

在服务器端,我们需要配置SingleSignOn阀和Realm或 “用户数据库”。这些配置在Tomcat安装的conf文件夹下的server.xml文件中。要添加SSO阀,我们需要取消对以下一行的注释。

<Valve className="org.apache.catalina.authenticator.SingleSignOn" />

For the article’s example, we’ll rely on the default configured Realm, and we’ll only need to add the users to the database. The Realm definition looks like this:

对于文章的例子,我们将依靠默认配置的Realm,我们只需要将用户添加到数据库中。Realm的定义看起来像这样。

<Realm
  className="org.apache.catalina.realm.UserDatabaseRealm"
  resourceName="UserDatabase"/>

This configuration uses a global JNDI resource to define the source of the user’s database:

这种配置使用一个全局JNDI资源来定义用户的数据库来源。

<Resource name="UserDatabase" auth="Container"
  type="org.apache.catalina.UserDatabase"
  description="User database that can be updated and saved"
  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
  pathname="conf/tomcat-users.xml" />

The resource will instantiate an object of type org.apache.catalina.UserDatabase and will populate it from the tomcat-users.xml file using the factory class org.apache.catalina.users.MemoryUserDatabaseFactory.

该资源将实例化一个org.apache.catalina.UserDatabase类型的对象,并使用工厂类org.apache.catalina. users.MemoryUserDatabaseFactory从tomcat-users.xml文件中填充该对象。

Finally, here we see how to add a user with the admin role required by the example of the article. We need to modify the tomcat-users.xml file:

最后,我们在这里看到如何添加一个具有文章中的例子所要求的管理员角色的用户。我们需要修改tomcat-users.xml文件。

<tomcat-users xmlns="http://tomcat.apache.org/xml"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
  version="1.0">
    <role rolename="admin"/>
    <user username="demo" password="demo" roles="admin"/>
</tomcat-users>

3.2. Web Apps Configuration

3.2 网络应用程序配置

Once we have configured the server, let’s configure the servlets through the web.xml configuration file that is inside the WEB-INF folder of each servlet.

一旦我们配置好了服务器,让我们通过每个Servlet的WEB-INF文件夹内的web.xml配置文件来配置Servlet。

All the web apps that require SSO must have protected resources and use one of the Tomcat authentication methods. As defined in the Servlet API specification 2.3, the authentication mechanism of the web apps is defined in a login-config element inside the web-app element. This element will contain an auth-method form that needs to use one of the following values: BASIC, DIGEST, FORM, or CLIENT-CERT. Each authentication method will have a different configuration, but we’ll discuss only the DIGEST and FORM authentication methods in the Tomcat Web Apps Configuration section.

所有需要SSO的Web应用程序必须有受保护的资源,并使用Tomcat认证方法之一正如Servlet API规范2.3所定义的,Web应用程序的认证机制在web-app元素内的login-config元素中定义。这个元素将包含一个auth-method表单,需要使用以下值之一。BASIC, DIGEST, FORM, 或 CLIENT-CERT。每种认证方法将有不同的配置,但我们将在Tomcat Web Apps 配置部分只讨论 DIGEST 和 FORM 认证方法。

To complete the web app configuration, we need to set up the protected areas. Inside the web.xml file under the web-app element, we can add as many security-constraint elements as needed. Each security constraint defines the URL pattern to the protected resources and will set the roles permitted. Furthermore, we need to define security-role elements with all the roles, and they must match the definitions in the tomcat-users.xml file. We’ll see an example in the next section.

为了完成Web应用程序的配置,我们需要设置保护区。在web.xml文件的web-app元素下,我们可以根据需要添加尽可能多的安全约束元素。每个安全约束都定义了受保护资源的URL模式,并将设置允许的角色。此外,我们需要用所有的角色定义安全角色元素,它们必须与 tomcat-users.xml 文件中的定义相匹配。我们将在下一节看到一个例子。

4. Example Authentication Mechanisms

4.认证机制实例

Now that we know how to configure the web apps, let’s see two examples: Ping and Pong. We have chosen different authentication mechanisms to show that the SSO works well with different mechanisms.

现在我们知道如何配置网络应用,让我们看看两个例子。Ping和Pong。我们选择了不同的认证机制,以显示SSO在不同的机制下工作良好

4.1. Ping Authentication Mechanism

4.1.Ping认证机制

At the ping web app, we use the FORM authentication method. FORM authentication method requires a login form, and the login failed the web page. For instance, this method will be useful when we want to customize the login page to look like the web app, and the configuration will look like this:

在ping网络应用程序,我们使用FORM认证方法。FORM认证方法需要一个登录表单,而登录失败的网页。例如,当我们想把登录页面定制成网页应用的样子时,这种方法将是有用的,配置将是这样的。

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/logging.html</form-login-page>
        <form-error-page>/logging_error.html</form-error-page>       
    </form-login-config>
</login-config>

The login page must follow some strict rules defined in the Login Form Notes of the servlet specification 2.3 because we can choose neither the names of the form nor the input fields. They must be j_security_checkj_username, and j_password. This is to achieve that the login form works with all kinds of resources and to remove the need to configure the action field of the outbound form in the server. Here we can see an example of what it must look like:

登录页面必须遵循servlet规范2.3的登录表单说明中定义的一些严格规则,因为我们既不能选择表单的名称,也不能选择输入字段。它们必须是j_security_checkj_usernamej_password。这是为了实现登录表单能与各种资源一起工作,并消除在服务器中配置出站表单的动作字段的需要。在这里,我们可以看到一个例子,它必须看起来像什么。

<!DOCTYPE html>
<html>
<head>
    <title>Ping - Login</title>
</head>
<body>
    <form method="post" action="j_security_check">
        <table >
            <tr>
                <td>User name: </td>
                <td><input type="text" name="j_username" size="20"/></td>
            </tr>
            <tr>
                <td>Password: </td>
                <td><input type="password" name="j_password" size="20"/></td>
            </tr>
        </table>
        <p></p>
        <input type="submit" value="Submit"/>
         
        <input type="reset" value="Reset"/>
    </form>
</body>
</html>

To understand what will happen on the server when it receives a request from a protected resource of a FORM authenticated web app, let’s summarize the flow of this authentication mechanism.

为了理解当服务器收到FORM认证的网络应用的受保护资源的请求时,服务器上会发生什么,让我们总结一下这个认证机制的流程。

First of all, the client requests a protected resource. If the server doesn’t contain a valid SSO session ID, the server will redirect the client to the logging form. After the user has filled out the form and sent its credentials to the server, the authentication mechanism will start.

首先,客户端请求一个受保护的资源。如果服务器不包含一个有效的SSO会话ID,服务器将把客户端重定向到登录表格。在用户填写完表格并将其凭证发送给服务器后,认证机制将开始。

After the user authentication succeeds, the server will check the roles of the user, and if the security constraint allows at least one of them, the server will redirect the client to the requested URL. In another case, the server will redirect the client to the error page.

在用户认证成功后,服务器将检查用户的角色,如果安全约束至少允许其中一个角色,服务器将把客户端重定向到要求的URL。在另一种情况下,服务器将把客户端重定向到错误页面。

4.2. Pong Authentication Mechanism

4.2.庞氏认证机制

At the Pong web app, we use the DIGEST authentication mechanism, and the configuration will look like this:

在Pong网络应用中,我们使用DIGEST认证机制,配置将是这样的。

<login-config>
    <auth-method>DIGEST</auth-method>
</login-config>

The DIGEST authentication mechanism flow is similar to the BASIC authentication: when the client requests a protected resource, the server returns a dialog box to request the user credentials. If the authentication succeeds, then the server returns the requested resource, but in another case, the server sends the authentication dialog box again.

DIGEST认证机制流程与BASIC认证相似。当客户端请求一个受保护的资源时,服务器会返回一个对话框来请求用户的证书。如果认证成功,那么服务器就会返回请求的资源,但在另一种情况下,服务器会再次发送认证对话框。

Although DIGEST and BASIC authentication methods are similar, there is an important difference: the password remains in the server.

尽管DIGEST和BASIC认证方法相似,但有一个重要的区别:密码仍然在服务器中。

4.3. Web Apps Security Constraint Configuration

4.3.网络应用程序安全约束配置

At this point, we aren’t going to make distinctions between Ping and Pong. Despite they having elements with different values, the important part of the configuration will remain the same in both apps:

在这一点上,我们不打算对Ping和Pong进行区分。尽管它们有不同值的元素,但配置的重要部分在两个应用程序中都将保持不变。

<security-constraint>
    <display-name>Ping Login Auth</display-name>
    <web-resource-collection>
        <web-resource-name>PingRestrictedAccess</web-resource-name>
        <url-pattern>/private/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
</security-constraint>

The security constraint defines that everything under the private folder is a protected resource and also defines the need to have an admin role to access the resources.

安全约束定义了私有文件夹下的所有东西都是受保护的资源,还定义了需要有一个管理员角色来访问这些资源。

5. Running the Example

5.运行实例

Now we need to install a Tomcat 10 server, adjust the configuration as shown previously in the article, and put Ping and Pong web apps under Tomcat’s web app folder.

现在我们需要安装一个Tomcat 10服务器,按照之前文章中所示调整配置,并将Ping和Pong的Web应用放在Tomcat的Web应用文件夹下。

Once the server is up and running, and both apps have been deployed, request the resource http://localhost:8080/ping/private. The server will show the login authentication because we aren’t logged in:

一旦服务器启动并运行,并且两个应用程序都已部署,请求资源http://localhost:8080/ping/private。服务器将显示登录认证,因为我们没有登录。

ping app login request

Then we need to introduce the credentials configured in the Tomcat server configurations section and submit the form. If the server validates the credentials, then we’ll see a web page with a link pointing to the pong’s private section:

然后我们需要引入在Tomcat服务器配置部分配置的凭证,并提交表格。如果服务器验证了凭证,那么我们就会看到一个网页,上面有一个指向庞的私人部分的链接。

ping app private page

In case the server doesn’t validate the access, we’ll see the login error page.

如果服务器没有验证访问,我们会看到登录错误页面。

ping app login error

After successful login to the Ping app, we could see the SSO mechanism in action, clicking the link to the pong’s private section. If the session is already active, the server will send the Pong’s protected resource without requiring that we login in again.

在成功登录Ping应用后,我们可以看到SSO机制在发挥作用,点击pong的私有部分的链接。如果会话已经激活,服务器将发送Pong的保护资源,而不要求我们再次登录。

pong app private page

Finally, we could check that after the session expires, the server will show the login page again. We can do that by waiting a couple of minutes and clicking the link to the ping’s private section.

最后,我们可以检查在会话过期后,服务器是否会再次显示登录页面。我们可以通过等待几分钟并点击ping的私人部分的链接来做到这一点。

6. Other SSO Solutions

6.其他SSO解决方案

In this article, we’ve covered the Web-SSO implemented by the Tomcat server. In case we want to explore other SSO options, here are some popular ones:

在这篇文章中,我们已经介绍了Tomcat服务器实现的Web-SSO。如果我们想探索其他的SSO选项,这里有一些流行的选项。

7. Conclusion

7.结语

In this tutorial, we’ve learned the basics of Tomcat architecture. Later on, we have reviewed how to configure the server. Finally, we have reviewed the configuration of the servlets or web apps that must be included under the SSO.

在本教程中,我们已经了解了Tomcat架构的基本知识。后来,我们回顾了如何配置服务器。最后,我们回顾了必须包含在SSO下的Servlet或Web应用程序的配置。

As usual, the complete source code is available over on GitHub.

像往常一样,完整的源代码可以在GitHub上找到