How to Configure Request Header Authentication in Nexus with Apache

Overview

Nexus request header authentication allows you to use an external system to validate the login credentials of users accessing Nexus Repository Manager or Nexus IQ Server. The validated user ID is sent to Nexus via an HTTP request header. Request header authentication is useful to implement single sign on (SSO), and is also useful for using authentication schemes which Nexus does not currently support, such as Kerberos or SAML.

This article will walk you through the steps needed to set up request header authentication for Nexus Repository Manager using the Apache web server. 

Configuration for Nexus IQ Server (CLM) is almost identical, except that the method used to configure the request header is different. See section 4.2.4 here for details:

It is recommended that you follow the steps in this guide and get everything working as described here before attempting to configure Apache for more advanced types of authentication. It is also recommended that you test each step after completing it before proceeding to the next step.

Step 1 - Configure Nexus for Security Authentication and Authorization via LDAP or Crowd

An HTTP request header can only be used for authentication (validation of login credentials) in Nexus. Authorization (mapping of users to Nexus roles and privileges) needs to be done via another mechanism. This will allow you to map groups defined in external servers such as Active Directory to sets of roles and privileges in Nexus. Instructions for configuring external user management systems in Nexus can be found here:

Once you have the integration with the external user management system working then you need to grant users in your external systems access to Nexus. There are two mechanisms available to do this:

For large numbers of users it is highly recommended to use external role mappings. It's far easier to manage users in a system such as Active Directory which has been specifically designed for the task.

Once you have your user mappings configured be sure to test it. Make sure the end users you've mapped in from the external authentication system can log into nexus and access the resources you've granted the access to.

Step 2 - Configure a Request Header Authentication in Nexus Repository Manager

The Nexus side of request header authentication is quite simple, we just need to let Nexus know what HTTP header is going to contain the authenticated user ID.

To set this up:

  1. Go to "administration/capabilities" in the UI
  2. Click on "new" to add a new capability
  3. Select the "Rut Auth" capability
  4. Fill in the header name. This article assumes you will use "X-Proxy_REMOTE-USER" as the header name.
  5. Save

When the capability is first created and marked Enabled, the RUT Auth Realm will automatically get added to the Selected Realms list under Administration -> Server -> Security Settings -> Selected Realms.

Make sure that this realm is added later manually if you initially add the capability but do not enable it.

For more information see here:

Step 3 - Configure Apache

Next we need to configure four things in Apache:

  1. Load the modules needed for this setup
  2. Configure basic authentication
  3. Set the X-Proxy_REMOTE-USER header
  4. Configure Apache as reverse proxy in front of Nexus

Step 3a - Load Modules

The following Apache modules will be needed in order to run the configuration below:

  • mod_proxy
  • mod_proxy_http
  • mod_headers
  • mod_rewrite

These can be loaded via LoadModule directives in httpd.conf. But different distributions of Apache will have modules loaded in different ways. It's best that you consult the documentation for your Apache distribution to find the recommended mechanisme for loading modules.

Step 3b - Configure Apache HTTP Basic Authentication

For testing purposes we are going set up simple authentication in Apache. This will be replaced later with a more secure authentication system.

Full instructions for setting up simple authentication in Apache can be found here:

Basically, you just need to run:

htpasswd -c /home/test/passwd username

The "htpasswd" command comes as part of your Apache distribuion:

Running the above command will prompt you for a password for user "username", and then write out a password file at the specified location. Additional users can be added with:

htpasswd /home/test/passwd <user-id>

Next, add a location directive into the http.conf file, and configure Apache for basic authentication using the password file you created previously:

<Location /nexus>
#Configure basic authentication (for testing purposes)
AuthType Basic
AuthName "Sonatype Nexus"
AuthBasicProvider file
AuthUserFile /home/test/passwd
Require valid-user
</Location>

You can test the above by visiting http://localhost/nexus in a browser. You should be prompted for authentication by the browser. Entering the credentials of one of the users you configured above should work.

Note: Web browsers will cache credentials entered for HTTP basic authentication until they are restarted. So you'll need to restart your browser to get the loging prompt again. Using HTTP basic browser authentication is only shown here for testing purposes, you should replace this with a more robust authentication mechanism for production purposes.

Step 3c - Set the Authenticated User ID in a Request Header

Authenticated users in Apache are made available via the REMOTE_USER server variable. Unfortunately there doesn't appear to be a way to make server variables directly available for setting in request header, so we need a bit of trickery:

# Make REMOTE_USER set by authentication available as environment variable
RewriteEngine on
RewriteCond %{REMOTE_USER} (.*)
RewriteRule .* - [E=ENV_REMOTE_USER:%1]
RequestHeader set X-Proxy\_REMOTE-USER %{ENV_REMOTE_USER}e

The RewriteRule rule above fires for every request and sets the environment variable ENV_REMOTE_USER equal to the value of REMOTE_USER, which is itself set by the apache authorization module. The RequestHeader sets a request header named X-Proxy_REMOTE_USER with the value of ENV_REMOTE_USER in the request sent to Nexus.

Additionally, we need to unset any authorization headers being sent from the original request, these aren't needed, and should not be sent to Nexus. This is accomplished with:

# Remove incoming authorization headers, Nexus users are authenticated by HTTP header
RequestHeader unset Authorization

Step 3d - Configure Apache as a Reverse Proxy

Next we need to configure Apache as a reverse proxy in front of Nexus. For testing purposes this will work:

# Configure apache as a reverse proxy for Nexus
ProxyPreserveHost on
ProxyPass http://localhost:8081/nexus
ProxyPassReverse http://localhost:8081/nexus

Additional configuration will likely be needed for production, particularly if you are using Apache to serve SSL (http) pages. You can find full documentation for configuring Apache as a reverse proxy for Neuxs here:

Step 3e - Completed Configuration

For reference, here is the full configuration from above:

<Location /nexus>
#Configure basic authentication (for testing purposes)
AuthType Basic
AuthName "Sonatype Nexus"
AuthBasicProvider file
AuthUserFile /home/test/passwd
Require valid-user

# Make REMOTE_USER set by authentication available as environment variable
RewriteEngine on
RewriteCond %{REMOTE_USER} (.*)
RewriteRule .* - [E=ENV_REMOTE_USER:%1]
RequestHeader set X-Proxy\_REMOTE-USER %{ENV_REMOTE_USER}e

# Remove incoming authorization headers, Nexus users are authenticated by HTTP header
RequestHeader unset Authorization

# Configure apache as a reverse proxy for Nexus
ProxyPreserveHost on
ProxyPass http://localhost:8081/nexus
ProxyPassReverse http://localhost:8081/nexus
</Location>

Step 4 - Restrict the IP subnet for Nexus

In order to make the above configuration secure you must restrict access to Nexus by subnet or IP address. Without this restriction a user could bypass the Apache instance and log directly into Nexus, or worse, they could craft a malicious request with the remote user header set and gain access to resources they should not normally be able to see.

There are two ways you can restrict access, by subnet, or by IP address. Restriction by subnet is easiest, and is usually sufficient, particularly if Apache and Nexus are running on the same machine.

To restrict by subnet edit $NEXUS_HOME/conf/nexus.properties and look for this line:

application-host=0.0.0.0

This line is telling Nexus to listen for connections on all network interfaces. To restrict this, simply replace "0.0.0.0" with the IP address of the network interface which is on a restricted subnet. For example, if both Nexus and Apache are on the same machine then you can tell Nexus to only listen on the loopback network:

application-host=127.0.0.1

Restriction by IP address is a bit more complex, see here for details:

Step 5 - Replace Basic Authentication with a More Robust Security Mechanism

It is beyond the scope of this article to cover more advanced authorization schemes such as Kerberos, this is left as an exercise to the reader. Apache supports a wide variety of authorization schemes, a web search will turn up lots of information on how to get these working.

Here are a few resources for Kerberos that you may find useful:

Apache supports many other authentication systems, such as Oath, SAML, etc. There are lots of tutorials and examples available on the web for these.

Have more questions? Submit a request

3 Comments

  • 0
    Avatar
    Andreas Panagiotidis

    Thanks for the article Rich.

    After some experimentation with Nexus Rut Authentication, I realised that it is not enough to just add the "Rut Ath" Capability in Nexus OSS Capabilities.

    You have also to add the Rut Auth Realm in the selected realms in Nexus -> Server -> Security Settings. Make sure it comes after the XML Realms.

    I hope that my comment saves lots of time to other fellow Nexus users.

  • 0
    Avatar
    Peter Lynch

    Andreas,

    Thanks for the comment. The reason we didn't mention adding the RUT Auth realm is because it should automatically get added when the capability is created and enabled the first time. However, I can see that it may be possible to create the capability initially not enabled, leading to your situation.

    I will add a bit of clarification to the article.

     

  • 0
    Avatar
    Peter Lynch

    We are closing this article for comments.

    If you have a support license, please contact us by submitting a support ticket.

    If you do not have a support license, please use our Nexus Users List or our other free support resources.

Article is closed for comments.
Powered by Zendesk