tl; dr如何根据Spring配置文件排除类包含在bootJar
生成的jar文件中?
我会故意含糊不清,但会尽量提供尽可能多的信息。
我有一个C#。NETweb api(JSONHTTP/1.1)。这个api从第三方接收一个加密的有效负载。这个第三方有一个为Java编写的库,但不是C#。由于时间限制和其他因素,我们决定用Spring Boot建立一个JavaAPI,并调用该API,而不是自己实现它们的库。
流量是
我们有一套目前用C#编写的自动化集成测试。
我们需要确保,给定一个有效的有效负载,当它被发送到C#API时,有效负载被转发到JavaAPI,被正确解密,被正确转换,并被正确重新加密以供其他第三方处理。
为了促进这一点,我在JavaAPI上创建了一个新控制器,它接收明文有效负载,对其进行加密(就像第三方一样)并将其返回给调用者。然后,调用者可以发送加密的有效负载,在JavaAPI上执行不同的控制器来进行解密验证,并将重新加密的有效负载发送回调用者。
JavaAPI信任这些自动化创建的有效负载。JavaAPI在运行时生成一个新的密钥对,当它收到明文有效负载时,它使用运行时生成的私钥对其进行签名,并信任使用运行时生成的公钥签名的消息。
我现在的问题是,我不希望这个功能在生产中可用。这些有效负载的内容太敏感了,坏人无法操纵。
我通过向控制器添加@Profile("test")
属性解决了部分问题。这允许我在运行时配置它,例如
java -jar sensitive-app.jar --spring.profiles.active=production
这样,在运行时,Spring会阻止控制器工作
{
"timestamp": "2018-03-16T23:20:00.781+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/dangerous-endpoint"
}
但是,我知道没有什么是不可破解的。尽可能地,我想确保这不会被任何访问盒子的不良行为者击中;或者换句话说,即使攻击者访问了盒子,并以
java -jar sensitive-app.jar --spring.profiles.active=test
控制器仍然无法正常工作。
我正在使用spring-boot gradle插件构建这个jar。
我能想到的唯一方法是首先防止控制器被包含在jar中。
我尝试将此添加到我的构建脚本中
bootJar {
exclude('sensitive/dangerous/**')
}
但是我看到类文件仍然包含在jar中。
然后我想知道是否有某种方法可以让Spring插件根据属性智能地包含或排除文件,例如
gradlew clean build bootJar -Dspring.build.profile=production
但什么也找不到。
我还试图排除源集中的文件
sourceSets {
main {
java {
if (project.environment == 'prod') {
exclude '**/dangerous/**'
}
}
}
}
但是class文件仍然在jar文件中(在BOOT-INF/class
文件夹下)
注意:此控制器需要在所有非生产环境中可用,因此不能直接编译此文件。
如何将类排除在bootJar
生成的jar文件中;或者有没有一种方法可以告诉gradle构建将包含在Spring配置文件中的文件?
我会采取不同的策略。
我会编写危险控制器,以便它在JVM环境中寻找非常特定的东西(例如自定义系统属性或环境变量)。
>
让控制器测试变量,如果检测到它正在生产中使用,则抛出异常。大声失败,而且很早!可能将其放入静态初始化程序中,以便在控制器加载/连接时发生故障。
安排属性/变量/任何设置的方式不能被您选择的构建/部署方法论意外复制到生产环境中。(有多种方法可以做到这一点…但是你故意对上下文含糊其辞,这使得很难提出合适的方法。)
这种方法的优点是它应该不受干扰构建脚本的人的影响。但是建议通过构建脚本也排除控制器。(腰带和括号…)
您可以使用gradle源集来做到这一点。
def env = project.hasProperty('env') ? project.env : 'development'
sourceSets {
main {
java {
srcDir 'src'
if ( env == 'production' ) {
println "DANGEROUS source set is being used for project complie (env = $env)!"
} else {
println "SAFE source set is being used for project complie (env = $env)."
exclude '**/dangerous/**'
}
}
}
}
使用危险的Java代码调用进行编译:
gradle clean build bootJar -Penv=production
如果您使用的是IDE,它可能不尊重您声明的源代码集。您必须使用gradleIDE(eclipse、Ide)插件并添加相同的逻辑。
在部署到各种环境时,通常可以通过CI作业传入此类内容。此外,您可以将application.properties文件加载到gradle或使用系统属性来确定环境。