With NGINX being the most ubiquitous web server and reverse proxy on the market, it makes NGINX the perfect place to inject authentication to protect access to critical APIs and web resources. For the purposes of this article, I will be discussing the most common modern authentication methods being OpenID Connect and/or JWT validation. Using modern authentication methods allows great flexibility to put auth in front of legacy web applications, modern APIs, and even new Web3 applications that rely on the blockchain. We will also primarily be focused on NGINX+ as the commercial subscription provides additional functionality not found in the Open-Source releases, however, most of this is accomplishable in the Open-Source release with custom code.
OpenID Connect
OpenID Connect is quickly becoming the most popular way to provide federated authentication for web applications with many popular Identity Services using it as a preferred method such as those services provided by Google, Microsoft Azure, Okta, OneLogin, etc. It is also well supported by on-premises identity providers such as ADFS (Microsoft Active Directory Federation Services) or RedHat SSO (Keycloak) for applications that might be fully internal to an organization. NGINX fully supports leveraging your preferred Identity Provider via OpenID Connect when using the Commercial Subscription NGINX+ by way of the auth_jwt module and the key-value store it enables.
F5 provides a good starting point by way of their public example GitHub repo as well as a configuration script that works well for most basic implementations. It should be viewed as a starting point to be used for customization around a specific application needs around authentication. This repo can be found here: https://github.com/nginxinc/nginx-openid-connect/.
JWT Validation
JWTs (JSON Web Tokens) have become the defacto standard for API authentication and can be consumed by NGINX+ in several ways. As the underlying mechanism for OpenID Connect JWTs are already widespread in the browser use-case, but standalone they are also the most widely used mechanism for the authentication of API traffic as well. F5 provides good starting documentation for this use case, however, as with OpenID Connect, this should be viewed as a starter baseline with customizations required for most implementations. These docs can be found here: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/. NGINX+ can be configured to consume JWT’s in a wide variety of ways that we will discuss in the sections below:
Basic Pre-Authentication
The most basic use case would be to have NGINX+ perform pre-authentication of requests by way of consuming a JWK file off disk or via web call to the identity provider. The JWK contains the keys needed to validate and decrypt the data inside of a JWT. In this use case, NGINX+ would do a minimal check ensuring that the JWT is valid without doing any deeper inspection. This can be very useful where you need NGINX to filter or drop unauthenticated requests, but your application is perfectly capable of decoding your JWTs and consuming the claims within them. We will typically deploy this sort of configuration where NGINX+ is being used as a traffic gatekeeper blocking malicious traffic, performing rate limiting, potentially operating as a WAF using NGINX App Protect, and even when leveraging NGINX App Protect DOS to act as a DDOS filtering layer.
Pre-Authentication with Claims Inspection
In addition to the basic JWT validation outlined above NGINX+ can also consume arbitrary claims from the JWT to provide enhanced pre-authentication of client traffic. This could be something as simple as checking that the audience in the claim is appropriate to full validation of the scope within the claim. This functionality can be quite useful where you have multiple back-end API endpoints that might have varying user groups all protected by the same NGINX+ frontend that can drop illegitimate calls saving your back-end application servers resources.
Nested JWT Extraction
For high-security use cases where you need to ensure that sensitive information is protected in transit, you may choose to use Nested JWTs. Nested JWTs offer an extra layer of protection where the token is encrypted with the consumer’s public key after it is signed with the issuer’s private key. Decrypting JWTs can often add a high layer of overhead to backend application servers as they now need to perform a decryption operation for each request. This can be offloaded to NGINX+ where it can inspect the incoming nested JWTs, perform pre-authentication, and then pass the decrypted token on to the backend application for consumption without the encryption overhead.
JWT Token Introspection
Token Introspection would be the most “intensive” mechanism by which to validate a JWT by querying the token issuer for information about the token, to include validity. This can be a great way to pre-authenticate or even fully authenticate requests at the NGINX layer of your infrastructure. Another use case is when you need to be absolutely sure a token is valid or when using opaque tokens that require introspection to consume claims. F5 has provided a great starter example of how to do this using njs (NGINX JavaScript not to be confused with NodeJS). However, this almost always requires custom modifications when implemented in a production environment. Additionally, we can leverage the power of NGINX caching or NGINX+ key-value storage to cache responses, reducing the load on the token issuer. These examples can be found on the NGINX Demo GitHub repo here: https://github.com/nginxinc/NGINX-Demos/tree/master/oauth2-token-introspection-plus
I hope this quick article has been informative about some of the ways NGINX+ can be used to provide modern authentication or pre-authentication in front of your applications and API services. If this is an area where you are looking for help within your environment, please contact us and we’d be more than happy to discuss professional services around getting authentication going in your environment by leveraging the power of NGINX+.
Leave a Reply