背景:我在使用官方Maven从Gitee仓库下载依赖出现Failure to Authentication:403 Forbidden的问题,在经过一番测试和分析之后,找到原因并成功实施。
摘要:本文主要介绍构建Gitee私人Maven仓库的步骤,以及提出相关问题的解决方案。
文章目录
- 上传jar包
- 将jar包发布到本地仓库
- 本地仓库目录初始化为git目录,将所有文件推送到远程仓库
- 引用远程仓库的jar包
- 其他操作
- 发布时加入源码包
- SNAPSHOT版本会自动携带时间戳问题
- 下载依赖时出现Authentication Failed 403 Forbidden
上传jar包
使用Gitee构建仓库需要两个步骤:
- 将jar包发布到本地仓库
- 将本地仓库目录初始化为git目录,将所有文件推送到远程仓库
将jar包发布到本地仓库
该步骤主要需要配置一个仓库目录,由于该目录需要初始化为git目录并推送到远程仓库,一般需要跟Maven配置的Local Repository区分开。确认了仓库目录之后,在项目的pom.xml中加入以下配置:
<project>
...
<distributionManagement>
<repository>
<id>gitee</id>
<url>file:${user.home}/.m2/own</url>
</repository>
</distributionManagement>
...
</project>
其中url标签的值仓库目录,id标签的值为标识,更多关于distributionManagement
标签的信息参考:https:///pom.html#Repository。配置完成之后在项目下运行mvn deploy
即可在本地仓库目录下生成项目的jar包、checksum文件、meta文件等。
本地仓库目录初始化为git目录,将所有文件推送到远程仓库
distributionManagement.repository.url
标签配置的位置为本地仓库目录,使用git init
将本地仓库目录目录初始化为git仓库,并配置远程仓库地址,将所有文件推送到远程仓库即可。
引用远程仓库的jar包
<project>
...
<repositories>
<repository>
<id>gitee</id>
<url>https://gitee.com/delin10/test/raw/master</url>
<releases>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
...
</project>
releases
, snapshots
:分别表示release版本和snapshots版本(带有-SNAPSHOT后缀)的配置
enabled
:如果值为true,则允许从仓库下载release版本或者snapshot版本的包;否则不允许
updatePolicy
: 该标签用于配置maven更新仓库里jar包的频率。每次进行刷新时,Maven会比较当前时间戳和lastUpdated时间戳(该时间戳保存在maven-metadata-*.xml文件中)。参数值可能为:
-
always
:每次执行mvn都会进行检查远程仓库是否存在更新 -
daily
: 每天检查一次 -
interval:X
:X为自定义的更新的周期,单位:分钟 -
never
:从不进行检查
checksumPolicy
:当没有checksum文件或者checksum文件中的checksum是错误的,可以选择以下策略:
-
fail
:下载失败 -
warn
:输出警告信息 -
ignore
:忽略该异常
layout
:用于定义仓库的结构。Maven 2 & 3使用的是default结构,Maven 1.x使用的是legacy结构
Note:gitee的repository url可以通过打开仓库中的某个文件,从地址栏截取获得,github也一样。如下图所示:
点击右上角的“原始数据”按钮,浏览器会跳转至文件原始下载链接:
其链接组成结构为:
https://gitee.com/<用户名>/<仓库名>/raw/分支名
如果仓库下还存在文件夹,则需要在后面追加路径,比如我的仓库(如下图所示),则我的仓库地址为:https://gitee.com/delin10/repository/raw/master/repo
Maven的依赖下载模式为:<仓库地址>/<groupId>/<artifactId>/<version>/<artifactId>-<version>.pom
其他操作
发布时加入源码包
在pom.xml中加入下面配置
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
其中maven-source-plugin插件的作用是将项目源代码打包成jar包,该配置的重点在plugin
中的execution
标签,该标签定义的是该插件在Maven的生命周期的阶段。这里面的goal
一般会关联Maven生命周期的一个阶段,jar是指在打包(package)阶段会运行该插件。
SNAPSHOT版本会自动携带时间戳问题
- Maven 3无法通过添加-DuniqueVersion=false进行解决,原因如下:
截图来源:maven-deploy-plugin github源码
说明:从Maven 3.x开始不支持该参数
下载依赖时出现Authentication Failed 403 Forbidden
- 问题溯源:
查阅源码可知,Maven对User-Agent的定义为:
我们使用浏览器进行请求模拟,当使用Maven定义的User-Agent时,请求会出现403 Forbidden的情况
但是随意定义User-Agent或者使用火狐的User-Agent时,却可以访问Gitee仓库
Note:以上测试均在隐私窗口测试,对于已登录用户不存在此种User-Agent限制
总结一下上面几种情形:
1、使用FireFox User-Agent
2、使用Apache Maven User-Agent
3、随意定义User-Agent
只有当使用Maven定义的User-Agent时,下载Gitee仓库的文件才会出现403 Forbidden问题,很显然,Gitee后台是刻意对Maven进行了拦截。
- 解决方案:修改Maven代码并重新打包, 相关的教程查看代码仓库中的README;
源代码地址:https:///delin10/maven-wagon/tree/fix/gitee-forbidden
分支:fix/gitee-forbidden
修改部分:
wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java
wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/HeadersLoader.java