Azure Artifacts:フィードからの Maven の「401 Unauthorized」
Maven がリポジトリにユーザー名とパスワードを送るのは、pom.xml にあるそのリポジトリの <id> と同じ <id> の <server> が settings.xml にあるときだけです。なければ資格情報なしでフィードに聞き、Azure Artifacts は 401 を返します。つまりこの 401 は、合う server がなかったか、そこにあるパスワードが受け付けられなかったかのどちらかです(パイプラインからのこれについての Stack Overflow の質問は1万回近く見られています)。
プルリクエストのビルド検証で Maven のビルドが失敗しているなら、プルリクエストはそれを待っています:JetBrains IDE のプラグイン Azure DevOps Pull Requests は、プルリクエストのブランチ ポリシーを状態つきで IntelliJ IDEA に並べ、Pro ならフィードがビルドを通すようになったあとに、失敗したビルド ポリシーをもう一度動かせます。JetBrains Marketplace で入れる
どう見えるか
- Maven 3.9:
Could not transfer artifact com.fabrikam:fabrikam-tools:pom:1.0.0 from/to shared (https://pkgs.dev.azure.com/fabrikam/_packaging/shared/maven/v1): status code: 401, reason phrase: Unauthorized (401)。 - それより前の Maven:
Authentication failed for https://pkgs.dev.azure.com/fabrikam/_packaging/shared/maven/v1/…/fabrikam-tools-1.0.0.pom 401 Unauthorized。依存先についてのFailed to read artifact descriptor forのあとに出ることがよくあります。 mvn deployでは、Failed to deploy artifactsのあとに同じ終わり方をします。Maven Central からの依存先はダウンロードできていることもあります。断られているのはフィードだけです。
server の id とリポジトリの id
- Azure Artifacts の Connect to feed で Maven を選ぶと、
pom.xml用とsettings.xml用の2つのスニペットが出ます。<repositories>と<distributionManagement>にある<repository>の<id>は、<server>の<id>と1文字も違わず同じでなければなりません。片方の名前を変えたら、もう片方も変えます。 settings.xmlに、リポジトリをフィードへ回す<mirror>があるなら、Maven はミラーの<id>で server を探します。資格情報はその id の下に書きます。- パスワードは Packaging のスコープを持つ個人用アクセス トークンです。復元には Read、デプロイには Read & write が要ります。ユーザー名は空でなければ何でもかまいません(Microsoft のプロジェクト設定のページにそう書かれています)。Microsoft の例では組織名か
AzureDevOpsです。トークンの期限が切れると、401 が戻ってきます。 - プロジェクト スコープのフィードは、アドレスにプロジェクトが入ります:
…/fabrikam/Web/_packaging/shared/maven/v1。組織スコープのフィードには入れません。 - トークンの入った
settings.xmlは、リポジトリではなく自分のユーザー フォルダー(~/.m2/settings.xml)に置きます。
パイプラインでは:Maven の前に MavenAuthenticate
- Maven のステップの前に、
artifactsFeeds: sharedを書いた- task: MavenAuthenticate@0を足します。このタスクは、エージェントのユーザーの~/.m2/settings.xmlに、フィードの名前の<server>を足します。なのでpom.xmlのリポジトリの<id>は、フィードの名前にします(タスクのリファレンス)。ほかの組織のフィードはmavenServiceConnectionsに書きます。 mvn -sで自分のsettings.xml(たとえばセキュア ファイル)を使うときは、タスクはそのファイルに届きません。<username>AzureDevOps</username>と<password>${env.SYSTEM_ACCESSTOKEN}</password>の server を自分で書き、Maven のステップにトークンを渡します:env: SYSTEM_ACCESSTOKEN: $(System.AccessToken)。この行がないと、ステップにその変数はなく、フィードは 401 を返します。- MavenAuthenticate を置いたら、Maven のタスクの
mavenAuthenticateFeedは既定の false のままにします。ある質問では、401 で失敗していたデプロイが、質問者がこれを false に戻すと動きました。
資格情報はあるのに 401 か 403
- ビルド ID がフィードのロールを持っていません。復元には Feed Reader、デプロイには Feed Publisher (Contributor)、Maven Central のようなアップストリームからパッケージを保存するには少なくとも Feed and Upstream Reader (Collaborator) が要ります。ロールも、2つのビルド ID も、スコープの設定も NuGet と同じです:Unable to load the service index for source。
- フィードが別のプロジェクトにあります。MavenAuthenticate のリファレンスにあるとおり、そのプロジェクトで、パイプラインのビルド サービスにアクセスを与えます。
Gradle
- Gradle はそれだけでは
settings.xmlを読まないので、MavenAuthenticate は助けになりません。Microsoft の Gradle 8.2 以降向けの設定が使うcredentials(PasswordCredentials)では、build.gradleのリポジトリのnameから名前をとった2つのプロパティ、sharedUsernameとsharedPasswordを読みます。ふつうは~/.gradle/gradle.propertiesに書きます(Microsoft の Gradle の設定)。それより前の Gradle 向けの設定は、代わりにsettings.xmlを読むプラグインを使います。 - パイプラインでは、Gradle のステップの環境変数で渡します:
ORG_GRADLE_PROJECT_sharedUsername: AzureDevOpsとORG_GRADLE_PROJECT_sharedPassword: $(System.AccessToken)。Gradle はORG_GRADLE_PROJECT_で始まる変数をプロジェクトのプロパティにします(Gradle のビルド環境のページ)。ビルド ID には、Maven と同じフィードのロールが要ります。
IntelliJ IDEA と Rider で Azure DevOps のプルリクエスト
Azure DevOps Pull Requests は、JetBrains IDE 2024.1 以降と Android Studio で動く Lesstep のプラグインです。git のリモートから組織・プロジェクト・リポジトリを読み、あなたのレビュー待ちのプルリクエストを IDE のツール ウィンドウに並べます。Azure DevOps Services でも Azure DevOps Server でも動きます。プルリクエストのブランチ ポリシーを状態つきで見せるので、通っていない必須のビルドがプルリクエストの隣に出ます。Pro なら、失敗したビルド ポリシーや期限の切れたビルド ポリシーをそこからもう一度動かせます。レビューの受信箱は無料、投票・コメント・完了・作成は Pro(30日の無料試用つき)。
Azure DevOps・Azure Artifacts・Azure Pipelines は Microsoft Corporation の商標、Apache Maven と Maven は Apache Software Foundation の商標、Gradle は Gradle, Inc. の商標、IntelliJ IDEA と Rider は JetBrains s.r.o. の商標です。このページはそのいずれとも提携しておらず、承認も受けていません。
ほかに:pip:401 Error, Credentials not correct for · npm:E401 Unable to authenticate · NuGet:Unable to load the service index for source · English