TL;博士
如何将类排除在bootJar
生成的jar文件中,具体取决于Spring配置文件?
我会故意模糊,但会尽量提供尽可能多的信息。
我有一个C#.NET web api(JSON over HTTP / 1.1)。该api从第三方接收加密的有效载荷。这个第三方有一个为Java编写的库,但不是C#。由于时间限制和其他因素,我们决定使用Spring Boot站起来使用Java API,并调用该API,而不是自己实现它们的库。
流程是
我们有一套自动集成测试,目前用C#编写。
我们需要确保,在给定有效负载的情况下,当它被发送到C#API时,有效负载将被转发到Java API,正确解密,正确转换,并为其他第三方正确地重新加密 - 处理。
为了促进这一点,我在Java API上创建了一个新的控制器,它接收明文有效负载,加密它(就像第三方那样)并将其返回给调用者。然后,调用者可以发送该加密的有效负载在Java API上执行不同的控制器以执行解密+验证,并将重新加密的有效负载发送回调用者。
Java API信任这些自动创建的有效负载。 Java API在运行时生成一个新的密钥对,当它收到明文有效负载时,它会使用运行时生成的私钥对其进行签名,并信任使用运行时生成的公钥签名的消息。
我现在遇到的问题是我不希望这个功能在生产中可用。这些有效负载的内容对于糟糕的演员来说太敏感了。
我通过向控制器添加@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/**'
}
}
}
}
但是类文件仍然在jar文件中(在BOOT-INF/classes
文件夹下)
注意:此控制器需要在所有非生产环境中都可用,因此无法直接阻止编译此文件。
如何排除某个类被包含在bootJar
生成的jar文件中;或者有没有办法告诉gradle构建将包含在Spring配置文件中的文件?
答案 0 :(得分:1)
我会采取不同的策略。
我会编写危险的控制器,以便在JVM环境中寻找非常具体的东西(例如自定义系统属性或环境变量)。
让控制器测试变量并在检测到它正在生产中使用时抛出异常。大声失败,早点!可能将其放入静态初始化程序中,以便在控制器加载/接线时发生故障。
安排属性/变量/以任何方式设置的内容都不会被您选择的构建/部署方法意外复制到生产中。 (有多种方法可以做到这一点......但是你有意对上下文进行模糊处理,因此很难建议合适的方法。)
这种方法的优点是它应该免受某人干扰构建脚本的影响。但建议通过构建脚本以及来排除控制器。 (腰带和牙套......)
答案 1 :(得分:0)
您可以使用gradle sourceSets执行此操作。
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,那么很多人都不会尊重您声明的源集。您将不得不使用gradle IDE(eclipse,idea)插件并添加相同的逻辑。
这样的东西通常可以在部署到各种环境时通过CI作业传递。 此外,您可以将application.properties文件加载到gradle中,或使用系统属性来确定环境。