背景介绍 上家公司中,对业务开发的安全极为重视,需要对Java代码和pom引用的jar组件做安全性扫描。安全部门提供的渠道是,对业务的src和lib压缩winrar后,通过winscp上传到指定的服务器,效率较为低下,我这里开发了一个Maven插件,实现了自动化上传。
1、自定义maven的步骤
1、修改pom中标签的值为maven-plugin
<groupId>com.xxx</groupId> <artifactId>security-plugin</artifactId> <packaging>maven-plugin</packaging>2、引入依赖
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.8.3</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.6.1</version> </dependency>3、使用注释或者注解方式(推荐使用注解)
注解:@mojo-name表示goal名字(id),default-value-默认调用阶段
4、部分代码
@Mojo(name = "upload-check",
defaultPhase = LifecyclePhase.PACKAGE)
@Execute(phase = LifecyclePhase.PACKAGE)
public class MainMojo extends AbstractMojo {
@Parameter(property = "checkComponentUploadFileName")
private String checkComponentUploadFileName;
@Parameter(property = "checkComponentHost", defaultValue = "xxx")
private String checkComponentHost;
@Parameter(property = "checkComponentPort", defaultValue = "xx")
private Integer checkComponentPort;
@Parameter(property = "checkComponentUserName",defaultValue = "xxxxx")
private String checkComponentUserName;
@Parameter(property = "checkComponentPassword",defaultValue = "xxxxx")
private String checkComponentPassword;
//===================================代码检查====================================================
@Parameter(property = "checkCodeUploadFileName" )
private String checkCodeUploadFileName;
@Parameter( property ="checkCodeHost", defaultValue = "xxxxx")
private String checkCodeHost;
@Parameter( property = "checkCodePort", defaultValue = "xx")
private Integer checkCodePort;
@Parameter( property = "checkCodeUserName",defaultValue = "xxxxxx")
private String checkCodeUserName;
@Parameter(property = "checkCodePassword",defaultValue = "xxxxx")
private String checkCodePassword;
@Parameter(property = "enableCheckCode",defaultValue = "true")
private Boolean enableCheckCode;
@Parameter(property = "enableCheckComponent",defaultValue = "true")
private Boolean enableCheckComponent;
@Parameter(defaultValue = "${project}")
MavenProject mavenProject;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("开启代码扫描:"+enableCheckCode);
getLog().info("开启组件扫描:"+enableCheckComponent);
if(enableCheckCode){
Log log =getLog();
log.info("\n");
log.info("----------代码安全扫描上传开始------------------");
if(StringUtils.isBlank(checkCodeUploadFileName)){
log.error("checkCodeUploadFileName参数为空!");
return;
}
String path = mavenProject.getBasedir().getAbsolutePath();
String sourcePath = path+ File.separator+"src";
String targetFile= path+File.separator+checkCodeUploadFileName;
log.info("扫描路径:"+sourcePath);
log.info("上传目标文件="+targetFile);
try {
// ZipUtil.zip(sourcePath,targetFile,true);
// String destPath ="";
String outRst = TarUtil.tarFiles(targetFile,new File(sourcePath));
System.out.println("outRst = " + outRst);
log.info("--------------启动上传到Fortify扫描服务器-------------");
uploadToServer(checkCodeHost,checkCodePort,checkCodeUserName,checkCodePassword,"/uploads",
targetFile,checkCodeUploadFileName);
log.info("--------------上传到Fortify扫描服务器结束-------------");
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info("----------代码安全扫描上传完成------------------");
}
if(enableCheckComponent){
Log log =getLog();
log.info("\n");
log.info("---启动组件安全扫描上传-----");
// mvnExcute();
String packaging = mavenProject.getPackaging();
String uploadFileName = checkComponentUploadFileName+"."+packaging;//xx.jar\xx.war
renameTargetJarFile(uploadFileName);
String buildOutputDir =mavenProject.getBuild().getDirectory();
String targetFile = buildOutputDir+File.separator+uploadFileName;
//2、 upload file
uploadToServer(checkComponentHost,checkComponentPort,checkComponentUserName,checkComponentPassword,"/upload",
targetFile,uploadFileName);
log.info("---组件安全扫描上传文件完成-----");
}
}
5、如何使用?
<finalName>PluginTestDemo</finalName>
<plugins>
<plugin>
<groupId>com.xxx</groupId>
<artifactId>xxx-securitycheck-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<!-- 这里是需要指定上传安全服务器的文件名-->
<checkCodeUploadFileName>测试_my-test.0_xxx-jdk1.8.tar</checkCodeUploadFileName>
<checkComponentUploadFileName>
测试_xx-test2.0_user
</checkComponentUploadFileName>
<enableCheckCode>true</enableCheckCode>
<enableCheckComponent>true</enableCheckComponent>
</configuration>
<executions>
<execution>
<id>upload-check</id>
<phase>package</phase>
<goals>
<goal>upload-check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
6、说明
由于安全扫描服务器部署在公司内网,使用涉及到公司的服务器地址、端口和账号密码,为严格遵守公司的安全规定,生成的maven组件不能上传到apache maven仓库里,给大家使用。我上传到了公司内网的Maven 仓库,使用时候只需要pom做引用(前提是,在maven的/conf/setting.xml中设置好了公司仓库) 上面的pom引用中,如果从公司的maven仓库中拉取不到(有同事在使用过程,确实出现奇怪的现象),可以将maven 插件直接放到本地仓库中。
上述的引用例子和代码中,我去掉了部分和公司相关信息。