在 Azure 应用服务中配置 Tomcat、JBoss 或 Java SE 应用的安全性

本文介绍如何在应用服务中配置特定于 Java 的安全设置。 在应用服务中运行的 Java 应用程序实施与其他应用程序相同的一套安全最佳做法

Azure 应用服务以三种形式在完全托管的服务上运行 Java Web 应用程序:

  • Java SE - 可以运行作为 JAR 包(其中包含嵌入式服务器)部署的应用(例如 Spring Boot、Dropwizard、Quarkus,或包含嵌入式 Tomcat 或 Jetty 服务器的应用)。
  • Tomcat - 内置的 Tomcat 服务器可以运行作为 WAR 包部署的应用。

注意

对于 Spring 应用程序,我们建议使用 Azure Spring Apps。 但是,你仍然可以使用 Azure 应用服务作为目标。

对用户进行身份验证(简易身份验证)

在 Azure 门户中使用“身份验证和授权”选项设置应用身份验证。 在此处,可以使用 Microsoft Entra ID 或社交登录(如 GitHub)启用身份验证。 仅当配置单个身份验证提供程序时,Azure 门户配置才起作用。 有关详细信息,请参阅将应用服务应用配置为使用 Microsoft Entra 登录以及其他标识提供者的相关文章。

Spring Boot 开发人员可以使用 Microsoft Entra Spring Boot Starter 通过熟悉的 Spring Security 注释和 API 来保护应用程序。 务必增加 application.properties 文件中的最大标头大小。 我们建议值为 16384

Tomcat 应用程序可通过将 Principal 对象强制转换为 Map 对象这种方式,直接从 Servlet 访问用户的声明。 Map 对象会将每个声明类型映射到该类型的声明集合。 在下面的代码示例中,requestHttpServletRequest 的一个实例。

Map<String, Collection<String>> map = (Map<String, Collection<String>>) request.getUserPrincipal();

现在,你可以检查 Map 对象是否有任何特定的声明。 例如,以下代码片段循环访问所有声明类型,并输出各集合的内容。

for (Object key : map.keySet()) {
        Object value = map.get(key);
        if (value != null && value instanceof Collection {
            Collection claims = (Collection) value;
            for (Object claim : claims) {
                System.out.println(claims);
            }
        }
    }

若要将用户注销,请使用 /.auth/ext/logout 路径。 还可阅读关于 Tomcat HttpServletRequest 接口及其方法的官方文档。 以下 Servlet 方法是基于你的应用服务配置解除冻结的:

public boolean isSecure()
public String getRemoteAddr()
public String getRemoteHost()
public String getScheme()
public int getServerPort()

要禁用此功能,请创建一个名为 WEBSITE_AUTH_SKIP_PRINCIPAL 的应用程序设置,其值为 1。 若要禁用应用服务添加的所有 servlet 筛选器,请创建名为 WEBSITE_SKIP_FILTERS、值为 1 的设置。

配置 TLS/SSL

若要上传现有的 TLS/SSL 证书,并将其与应用程序的域名绑定,请按照在 Azure 应用服务中使用 TLS/SSL 绑定保护自定义 DNS 名称中的说明操作。 还可以将应用配置为强制实施 TLS/SSL。

使用 Key Vault 引用

Azure Key Vault 通过访问策略和审核历史记录提供集中式机密管理。 你可以在 Key Vault 中存储机密(例如密码或连接字符串),并通过环境变量在应用程序中访问这些机密。

首先,请按照说明执行以下操作:授予应用对密钥保管库的访问权限以及在应用程序设置中创建对机密的 KeyVault 引用。 你可以验证在远程访问应用服务终端时,该引用是否通过输出环境变量解析为机密。

请参阅有关外部化配置的文档来了解 Spring 配置文件。

若要在 Spring 配置文件中注入这些机密,请使用环境变量注入语法(即 ${MY_ENV_VAR})。

若要在 Tomcat 配置文件中注入这些机密,请使用环境变量注入语法(即 ${MY_ENV_VAR})。

在 Linux 中使用 Java 密钥存储

在容器启动时,系统会默认将上传到应用服务 Linux 的公用或专用证书都加载到各自的 Java 密钥存储中。 上传证书后,需要重启应用服务,以便将它加载到 Java 密钥存储中。 系统会将公用证书加载到位于 $JRE_HOME/lib/security/cacerts 的密钥存储中,将专用证书存储到 $JRE_HOME/lib/security/client.jks 中。

如果要在 Java 密钥存储中使用证书加密 JDBC 连接,可能需要其他配置。 请参阅适用于所选 JDBC 驱动程序的文档。

初始化 Linux 中的 Java 密钥存储

要初始化 import java.security.KeyStore 对象,请使用密码加载密钥存储文件。 这两个密钥存储的默认密码均为 changeit

KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/cacerts"),
    "changeit".toCharArray());

KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/client.jks"),
    "changeit".toCharArray());

手动加载 Linux 中的密钥存储

可以手动向密钥存储加载证书。 创建应用设置 SKIP_JAVA_KEYSTORE_LOAD,将其值设置为 1,以禁止应用服务自动将证书加载到密钥存储。 所有通过 Azure 门户上传到应用服务的公用证书都存储在 /var/ssl/certs/ 下。 专用证书则存储在 /var/ssl/private/ 下。

打开与应用服务的 SSH 连接并运行命令 keytool,即可与 Java 密钥工具进行交互或对它进行调试。 请参阅密钥工具文档,获取命令列表。 有关密钥存储 API 的详细信息,请参阅官方文档

后续步骤

请访问面向 Java 开发人员的 Azure 中心查找 Azure 快速入门、教程和 Java 参考文档。