Ohhnews

分类导航

$ cd ..
DZone Java原文

超越构建阶段:实现运行时的软件依赖项追踪与管理

#软件供应链#依赖管理#网络安全#api开发#软件架构

在开发现代软件时,开发人员通常会使用成百上千个依赖项。维护一份准确且一致的物料清单(Bill of Materials)对于许可合规性和安全性至关重要。

动机

在大型组织中,通过构建时扫描(build-time scanning)进行的依赖项审查存在一定的局限性:

  • 局限性一: 扫描通常针对单个项目。而大型组织可能拥有跨团队和部门开发的数百个应用程序,它们甚至可能使用同一依赖项的不同版本。
  • 局限性二: 它在脱离实际使用场景的情况下分析依赖项。例如,某些依赖项和指标在生产环境中的重要性高于测试环境。此外,有些构建到应用程序中的组件从未被使用,或者仅在特定环境下使用。
  • 局限性三: 当你不知道易受攻击的组件在何处或何时处于活动状态时,审查发现的问题并分析其影响会非常困难。
  • 局限性四: 在发现漏洞时,规划后续审查或进行临时检查需要耗费大量的时间和精力。

方案

考虑一种替代解决方案:让你的应用程序提供一个标准化的 API 端点,通过该端点可以获取当前活动依赖项的实时列表。当然,依赖项信息属于敏感数据,因此该 API 必须完全处于组织内部,并防止未经授权的访问。如果实现了这一点,自动监控系统就可以从实时实例中获取这些信息并将其存储在中央数据库中,从而提供准确、及时且可操作的软件供应链和生命周期概览。

在运行时审查依赖项列表,为开发人员提供了一个审视并完善其决策的绝佳机会。然而,考虑到数据的敏感性,也可以反转这一模式:由应用程序在启动时将列表提交给后端服务。这样,数据就可以在整个组织内以集中化的方式进行汇总和管理。

示例实现

我准备了一个用于提供专用 API 端点的概念验证(PoC),以及一个示例调度 UI,你可以在此找到:https://github.com/olddimplex/dependency-management

该项目使用 Maven 进行构建,但你完全可以使用其他框架实现同样的功能。在构建时,使用 Apache Maven Dependency Plugin 收集依赖项列表,并将输出类型设置为 graphml。如果你有兴趣将依赖项呈现为图表,该格式可直接由功能强大的 yEd diagram 编辑器读取。如果这样做,则需要手动定义布局,这正是编辑器的用武之地。生成的 XML 文件存储在类路径(class path)中,使其在运行时可用。

在配置方面,你只需将插件添加到 pom.xml 文件中,如下所示:

$ xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>tree</goal>
            </goals>
            <configuration>
                <outputType>graphml</outputType>
                <outputFile>src/main/resources/${project.name}-dependency-tree.xml</outputFile>
            </configuration>
        </execution>
    </executions>
</plugin>

这适用于项目的每个模块(如有)。信息在运行时进行汇总,因此你将看到所有模块的依赖项列表。由于依赖项本身也有依赖项,生成的图表是 XML 格式的树状结构。我们关注的是依赖项管理,因此仅从树中提取并汇总直接(顶级)节点。

我们提供了一个 API,用于向前端公开可管理的依赖项列表。

[LOADING...]

该 API 旨在与 DayPilot Pro for JavaScript 配合使用,但也可以通过其他方式实现。初始屏幕示例如下:

[LOADING...]

可见时间窗口的大小是可以配置的,本例中为当前日期起 1 年。你可以使用日历图标设置时间窗口的开始日期。除了依赖项列表外,还可以为每个依赖项定义计划事件列表。你可以使用鼠标添加事件,然后通过拖拽或调整大小(更改开始/结束时间)来操作它们。每个事件都有一个通过鼠标右键调用的上下文菜单。

演示程序中,事件数据仅保留在内存中。如果你需要持久化数据,可以实现所提供的接口。请记住,要在浏览器中查看依赖项,你需要提供自己的 DayPilot Pro for JavaScript 副本,并将其放置在项目源代码树中并进行引用。版本可能有所不同,下载试用版时即可获取。

在项目根目录下运行 mvn clean package。可执行的 .jar 文件存储在 target 子目录中。运行它会启动一个本地 Web 服务器(请留意控制台输出的端口),上下文路径为 /demo。例如,访问的 URL 可能是:http://localhost:8080/demo/dependency-management.html。此外,你可以在 http://localhost:8080/demo/swagger-ui/index.html 探索 API。

祝使用愉快!同样的方法也可以应用于具有类似架构的现有应用程序。欢迎分享你对此话题的想法。

结论

本文介绍了一种提高依赖项可见性和维护水平的概念,并为使用 Maven 进行生命周期管理的 Java 应用程序提供了一个示例实现,同时提出了未来的改进方向。