Azure Web App中通过CATALINA_OPTS访问Key Vault启动报错解决
Azure Web App(Tomcat9)配置Key Vault密钥引用启动失败
原有正常配置
我的Azure Web App(基于Tomcat9)原本通过META-INF/context.xml配置连接Azure SQL数据库,配置如下:
<Resource name="jdbc/myDB" type="javax.sql.DataSource" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" initialSize="30" maxActive="100" validationQuery="SELECT 1" validationQueryTimeout="1000" testOnBorrow="true" url="jdbc:sqlserver://myserver.database.windows.net:1433;database=myDatabase;encrypt=true;trustServerCertificate=true;loginTimeout=10;user=myuser@myserver;password=${dbPassword}" />
同时在Web应用配置中设置CATALINA_OPTS参数:
-Ddbpassword=<my password>
安全优化后的配置(导致启动失败)
为提升安全性,我在Key Vault中创建了名为DB-PASSWORD的密钥,并按照官方指引修改CATALINA_OPTS为:
-Ddbpassword=@Microsoft.KeyVault(SecretUri=https://thekeyvaulttest.vault.azure.net/secrets/DB-PASSWORD/)
报错信息
服务器启动失败,报错:
/usr/local/tomcat/bin/catalina.sh: eval: line 1: syntax error: unexpected "("
权限确认
Web App已具备读取该Key Vault密钥的权限,已排除认证类问题。
数据库连接Java代码
public final class DBConnection { private static DataSource ds = null; private static DBConnection instance = null; private DBConnection() throws NamingException { InitialContext ic = new InitialContext(); ds = (DataSource) ic.lookup("jdbc/mydb"); } public static synchronized DBConnection getInstance() { if (instance == null) { try { instance = new DBConnection(); } catch (Exception e2) { } } return instance; } public Connection getConnection() { Connection con = null; try { con = ds.getConnection(); } catch (SQLException e) { System.out.println(e.toString()); } return con; } public void returnConnection(Connection con) { try { con.close(); } catch (SQLException e) { System.out.println(e.toString()); } finally { try { con.close(); } catch (SQLException e) { System.out.println(e.toString()); } } return; } }
解决方案
将CATALINA_OPTS中的Key Vault引用值用双引号包裹,修改后的配置如下:
-Ddbpassword="@Microsoft.KeyVault(SecretUri=https://thekeyvaulttest.vault.azure.net/secrets/DB-PASSWORD/)"
原因说明
Tomcat启动脚本catalina.sh基于bash编写,当参数中包含(和)时,bash会将其识别为子命令解析符,触发语法错误。用双引号包裹整个Key Vault引用内容后,bash会将括号视为普通字符处理,同时Azure App Service的Key Vault引用解析逻辑仍能正确识别该格式,完成密钥的读取和注入。
内容的提问来源于stack exchange,提问作者gordon613
相关产品推荐
相关产品推荐

