Skip to content

tumbl3w33d/nexus-oauth2-proxy-plugin

Repository files navigation

OpenID Connect for Sonatype Nexus Artifact Repository

This plugin has been developed to facilitate the integration of Nexus with any identity provider that is compatible with OAuth2 Proxy.

Rather than executing its own OIDC (OpenID Connect) authentication flow, this plugin leverages OAuth2 Proxy to undertake the authentication process, relying on it to provide the necessary information through headers.

Furthermore, acknowledging the importance of non-interactive programmatic access within the Nexus environment, this plugin incorporates an API token feature. This feature ingeniously utilizes the password field of a local user object for storage purposes (acknowledged as a makeshift solution, with potential revisions anticipated). While users are unable to modify their passwords without prior knowledge of the existing one, the plugin introduces an additional endpoint. This endpoint enables authenticated users to reset their password to a system-generated one via the Nexus UI, with the caveat that this token is displayed solely once and is subject to reset with each access of the user menu item.

⚠️ State of Development & Disclaimer

The plugin currently encompasses the essential components required for operational functionality and is presently undergoing a testing phase. It is important to highlight that this plugin is provided on an 'as-is' basis, without any form of express or implied warranty. Under no circumstances shall the authors be held accountable for any damages or liabilities arising from the utilization of this plugin. Users are advised to proceed at their own risk.

Features

  • makes use of several headers sent by OAuth2 proxy (depending on its configuration)
  • creates a user in the local Nexus database if none with the given id (preferred_username) exists
    • anyone authenticated with your identity provider can access Nexus
    • you would control access by granting necessary scopes accessing OAuth2 Proxy only to eligible user groups
    • user creation currently has a rather simplistic strategy to extract <firstname>.<lastname> from preferred_username
  • reuses existing user object from another existing realm (e.g. LDAP)
    • ⚠️ this might not be appropriate for your setup, do your own testing or make sure there is no other realm active that holds user objects
  • group/scope to role sync
    • if you configure OAuth2 Proxy with the well-known groups claim, it will retrieve that information from the identity provider
    • the groups received in the related header will be mapped to roles that you need to (manually) create in Nexus
    • be aware that, in order to distinguish between role mappings connected with this realm and others, all groups will be prefixed with idp-, so name your roles accordingly and the user will magically receive/lose them on every login
    • Example: idp group devs@example.com will map to idp-devs@example.com role in Nexus
  • automatic expiry of API tokens
    • there is a configurable task that lets API tokens expire, so another interactive login by the user is necessary to renew it
    • as long as the user keeps showing up regularly, their token will not expire

Note: After authenticating with this realm, the logout button is non-operative, which is a common limitation with header-based authentication methods. To force a logout, you need to logout from your identity provider and/or delete the OAuth2 Proxy cookie if you must logout for some reason.

Necessary infrastructure

You typically put an OAuth2 Proxy in front of your application and make sure that related X-Forwarded- headers do not reach the application other than those originating from the OAuth2 Proxy.

For non-interactive programmatic access you circumvent the OAuth2 Proxy and go straight to the Nexus application. To achieve that, you could check for the presence of an Authorization: Basic header earlier in the chain of proxies. In that case the required credentials are the user's id and the generated API token. It is handled by the default implementation of Nexus and not touched by this plugin.

Example with HAProxy as entrypoint

# the entrypoint to your nexus + oauth2 proxy setup
frontend you-name-it
  # just illustrating that you must ensure TLS
  bind *:443 ssl crt /usr/local/etc/haproxy/cert alpn h2,http/1.1

  # if this is too invasive for your use case, be more specific
  http-request del-header ^X-Forwarded.*

  # circumvent oauth2 proxy for programmatic access
  acl is_basic_auth hdr_beg(Authorization) -i basic
  use_backend nexus if is_basic_auth

  default_backend oauth2-proxy


backend oauth2-proxy
  # interactive OIDC login
  option httpchk GET /ping
  server oauth2-proxy oauth2-proxy:4180 check


backend nexus
  # non-interactive programmatic access
  server nexus nexus:8081 check

Example OAuth2 Proxy config

reverse_proxy = true

http_address = "0.0.0.0:4180"

email_domains = [ "*" ]

# make sure to request group information for mapping to roles
scope = "openid email profile groups"

# your nexus is the backend
upstreams = ["http://nexus:8081"]

provider = "oidc"
oidc_issuer_url = "https://idm.example.com/consult/your/idp-documentation"
code_challenge_method = "S256" # PKCE, if your idp supports that
client_id = "get the client id from your identity provider"
client_secret = "get the secret from your identity provider"
cookie_secret = "generate an individual cookie secret"

# we don't need to wait for people to press the button, just redirect
skip_provider_button = true