401 Unauthorized and 400 Bad Request in Sonatype Nexus OSS
Today I was searching for a artifact repository to use in development, and was evaluating Sonatype's Nexus. Besides the fantastic documentation, the application itself seemed to have a good community supporting it. So, I decided to download and give it a try. It was easy to follow the installation manual and within 5 minutes I had everything installed and was ready to rumble. Here's a couple notes:
-
Don't run Nexus as root. It's a security issue. Make a user for them instead, or run it as your user in a home folder somewhere.
-
Read through the documentation, at least the first few chapters to get the concepts down.
-
Change the default passwords if this isn't a local nexus and can be reached within a network
Working with SBT was what I was interested in, and luckily Nexus has a chapter specifically on just that. Which got me mostly up and running. My build file ended up looking like this:
organization := "test"
name := "thing"
version := "0.0.1"
scalaVersion := "2.10.3"
scalacOptions += "-deprecation"
libraryDependencies <+= (scalaVersion)("org.scala-lang" % "scala-compiler" % _)
resolvers += "Nexus" at "http://localhost:8081/nexus/content/groups/public"
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
publishTo <<= version { v: String =>
val nexus = "http://localhost:8081/nexus/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "content/repositories/releases")
}
With a .ivy2/.credentials file:
realm=Sonatype Nexus Repository Manager host=127.0.0.1 user=admin password=admin123
I spent a lot longer than my initial 5 minutes on trying to get the publish
task in sbt to run though. I kept getting:
> publish [info] Wrote /Users/eeldridg/Sites/thing/target/scala-2.10/thing_2.10-0.0.1.pom [info] :: delivering :: test#thing_2.10;0.0.1 :: 0.0.1 :: release :: Thu Jul 02 11:56:02 EDT 2015 [info] delivering ivy file to /Users/eeldridg/Sites/thing/target/scala-2.10/ivy-0.0.1.xml [trace] Stack trace suppressed: run last *:publish for the full output. [error] (*:publish) java.io.IOException: Access to URL http://localhost:8081/nexus/content/repositories/releases/test/thing_2.10/0.0.1/thing_2.10-0.0.1.pom was refused by the server: Unauthorized [error] Total time: 0 s, completed Jul 2, 2015 11:56:03 AM
And after looking through a few posts on the web I finally got my Realm right
by checking the headers via curl.
curl -I -XPOST http://localhost:8081/nexus/content/repositories/releases/test/thing_2.10/0.0.1/drupalslick_2.10-0.0.1.pom -v > /dev/null
During this process I also tried out
curl -u admin:admin123 -I -XPOST http://localhost:8081/nexus/content/repositories/releases/test/thing_2.10/0.0.1/drupalslick_2.10-0.0.1.pom -v > /dev/null
Which returned successful, so I figure'd there wasn't an issue with my setup. However, a few minutes later of messing with the realm settings and credentials in SBT, I started getting a 400 error instead. By this point, I had all my loggers on Nexus turned up to maximum and was viewing errors like
2015-07-02 12:22:35,208-0400 DEBUG [qtp2141807259-51] anonymous org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter - Authentication required: sending 401 Authentication challenge response. 2015-07-02 12:22:51,885-0400 DEBUG [qtp2141807259-54] *UNKNOWN org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter - Attempting to execute login with headers [Basic YWRtaW46YWRtaW4xMjM=]
But wasn't seeing the 400. So instead, I turned towards the ever trusty tool: tcpdump!
Since I couldn't see the request on the Nexus side, I decided to watch what was happening
on the SBT side.
sudo tcpdump -i lo0 -n -s 0 -w -
And hitting publish one more time from the SBT CLI immediately got me the answer:
?!~/?!xHTTP/1.1 400 Bad Request
Date: Thu, 02 Jul 2015 16:23:05 GMT
Server: Nexus/2.11.3-01
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Accept-Ranges: bytes
Content-Type: text/html
Transfer-Encoding: chunked
2EA
<html>
<head>
<title>400 - Repository with ID='releases' does not allow updating artifacts.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="icon" type="image/png" href="http://localhost:8081/nexus/favicon.png">
<!--[if IE]>
<link rel="SHORTCUT ICON" href="http://localhost:8081/nexus/favicon.ico"/>
<![endif]-->
<link rel="stylesheet" href="http://localhost:8081/nexus/static/css/Sonatype-content.css?2.11.3-01" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<h1>400 - Repository with ID='releases' does not allow updating artifacts.</h1>
<p>Repository with ID='releases' does not allow updating artifacts.</p>
</body>
</html>
Derp! Of course I was getting a 400, since I wasn't versioning with a Snapshot, the
deployment policy on Nexus was refusing to change the empty POST request I had sent when
testing with curl. That's an easy fix in nexus though:
So let this be a helpful reminder to anyone else: Don't test a repository configuration with the release branch!