ExceptionFactory

Producing content that a reasonable developer might want to read

Supporting OIDC Refresh Tokens in Apache NiFi

NiFi Security OIDC

2023-05-13 • 8 minute read • David Handermann

Background

The OpenID Connect Core 1.0 specification includes a number of required and recommended integration features. Building on OAuth 2.0, OpenID Connect defines a standard for exchanging of identity information, in addition to describing common authentication flows. OpenID Connect Core 1.0 Section 12 outlines optional support for using Refresh Tokens to obtain new Access Tokens, enabling programmatic continuation of an authenticated session without prompting for user confirmation. As described in RFC 6749 Section 1.5, issuing a Refresh Token occurs at the discretion of the Authorization Server. OIDC Authorization Server implementations may or may not support Refresh Tokens based on specific product configuration settings. Most Refresh Tokens have long expirations lasting weeks or months. For this reason, RFC 7009 defines OAuth 2.0 Token Revocation, allowing clients to invalidate tokens on log out to mitigate potential security issues.

Introduction

Apache NiFi 1.21.0 included refactored support for OpenID Connect authentication based on Spring Security OAuth2. Rebuilding OIDC integration using Spring Security OAuth2 replaced a number of custom components with streamlined integration using standard filters and collaborating classes. The new design simplified frontend integration code and also enabled a token storage strategy designed according to Spring Security interfaces. Building on a secure token storage implementation, NiFi 1.21.0 supports Refresh Tokens and Token Revocation, improving both user experience and application security. With OpenID Connect capabilities varying from one product to another, the new NiFi implementation aims to support a number of Authorization Server configuration scenarios.

Application Sessions

For authentication strategies other than mutual TLS and single sign-on with Apache Knox, NiFi generates a JSON Web Token with an embedded expiration that controls the lifespan of an authenticated session. See Improving JWT Authentication in Apache NiFi for more details on the implementation along with important improvements in NiFi 1.15.0. After initial authentication, the application Bearer Token provides persistent access until it expires.

Session Expiration

Prior to version 1.21.0, NiFi OIDC integration derived Bearer Token expiration from the expiration of the ID Token. NiFi 1.21.0 altered this behavior to derive Bearer Token expiration from the expiration of the Access Token. For some Authorization Servers, both the Access Token and ID Token have the same expiration, meaning that changes in NiFi 1.21.0 will not alter the expiration of the application Bearer Token. For Authorization Servers that support different expiration settings for different token types, deriving the expiration from the Access Token enables more fine-grained configuration.

Session Continuation with Refresh Tokens

The source of Bearer Token expiration is important to understand as it relates to supporting Refresh Tokens. For Authorization Servers that do not support Refresh Tokens, NiFi session expiration follows the pattern of the previous implementation, requiring the user to interact with the Authorization Server when the Bearer Token expires. For Authorization Servers that return Refresh Tokens, however, NiFi 1.21.0 and following will continue to maintain the application session as long as the client browser remains open and the Refresh Token remains valid.

NiFi implements session continuation with Refresh Tokens by issuing a new Bearer Token when the current Bearer Token expiration is within a configurable refresh window. NiFi 1.21.0 introduced the following application property to control the window of time within which NiFi will attempt to exchange a stored Refresh Token with the Authentication Server.

nifi.security.user.oidc.token.refresh.window

The default refresh window is 60 seconds. As described in the NiFi documentation, given a Bearer Token with an expiration of one hour, NiFi will attempt to renew access 59 minutes after initial authentication. Renewing a Bearer Token requires an HTTP request from the authenticated client browser. If NiFi does not receive an HTTP request within the configured refresh window, the Bearer Token will expire as usual and subsequent access will require user interaction with the Authorization Server. This implementation strategy handles scenarios where a user closes a client browser without going through the logout process. NiFi uses a background thread to delete stored Refresh Tokens for expired application sessions.

Scope Configuration for Refresh Tokens

OpenID Connect Core 1.0 Section 11 describes Offline Access as one scenario in which an Authorization Server may grant Refresh Tokens. The section notes that Authorization Servers may grant Refresh Tokens in other contexts, but sending offline_access as one of the requested scopes is a common approach for OIDC implementations.

Requesting the offline_access scope does not guarantee that an Authorization Server will return a Refresh Token, but some providers require the scope in addition to enabling Refresh Token support in the Authorization Server configuration. The following NiFi application property instructs the OIDC implementation to send offline_access when requesting authentication tokens:

nifi.security.user.oidc.additional.scopes=offline_access

Bearer Token Refresh Process

The application Bearer Token refresh process relies on recurring status requests from the NiFi user interface. The interface issues repeated requests to gather current system information, including current user status.

The OidcBearerTokenRefreshFilter contains the request filtering and processing for Bearer Tokens using stored Refresh Tokens. The filter evaluates HTTP requests for the current user and determines whether the Bearer Token expiration is within the configured refresh window. When filter decides that the Bearer Token should be refreshed, the application loads stored OIDC tokens and checks for the existence of a Refresh Token. On finding a Refresh Token, the application attempts to exchange the Refresh Token with the Authorization Server for a new Access Token. Following a successful exchange, the application generates a new Bearer Token, returning the Bearer Token to the client browser in a session cookie that replaces the previous Bearer Token.

The Bearer Token refresh process can fail at various points, producing warning messages in the NiFi log. The client browser will continue to function after refresh failures and will follow standard authentication prompts when the existing Bearer Token expires. Based on this implementation, the client browser can continue accessing the application until the Refresh Token expires or the user initiates the logout process. NiFi will follow the Bearer Token refresh process according to the expiration and configured refresh window.

For example, an Authorization Server that sets an expiration of five minutes for Access Tokens will result in NiFi attempting to refresh the application Bearer Token every five minutes. This will generate more network requests between NiFi and the Authorization Server, but it enables stronger access control. With shorter expiration for Access Tokens, integrated applications such as NiFi will reflect account changes more quickly.

Secure Token Storage

NiFi OIDC support implements the Authorization Code Grant Type as described in RFC 6749 Section 4.1. The NiFi web application operates as a confidential client when communicating with the configured Authorization Server. As a confidential client, the application follows the requirements of RFC 6749 Section 10.4, protecting access to Refresh Tokens both in transit and in storage. The secure token storage implementation leverages the configured local State Provider, which uses the file system to store and retrieve state information. The local State Provider avoids sharing state with external cluster services, which mitigates some potential security risks associated with storing Refresh Tokens. The token storage implementation also encrypts each Refresh Token using the configured Sensitive Properties Key. This encryption and decryption process provides the same level of protection for Refresh Tokens as the framework applies to sensitive values in the flow configuration. A scheduled process also removes stored tokens for expired sessions, avoiding unnecessary persistence for users no longer accessing the application.

Session Termination

NiFi OIDC integration has supported several logout strategies in recent releases. NiFi supports OpenID Connect RP-Initiated Logout 1.0, which defines a method for a Relying Party, such as NiFi, to close active sessions through the configured Authorization Server. Support for RP-Initiated Logout varies, but without the end_session_endpoint defined in the OpenID Connect Discovery Document, NiFi is unable to close a session with the Authorization Server. With or without RP-Initiated Logout, NiFi attempts to revoke stored tokens before clearing the application Bearer Token.

Token Revocation

RFC 7009 is an extension of the OAuth 2.0 standard that defines the HTTP request and response structure for revoking Access Tokens or Refresh Tokens. NiFi 1.20.0 and earlier incorporated revocation in the absence of RP-Initiated Logout, but with the addition of Refresh Token support and persistent storage, token revocation provides an important layer of security.

The Spring Security OAuth2 libraries support a number of OAuth 2 and OpenID Connect features, but they do not provide direct support for Token Revocation. The new StandardTokenRevocationResponseClient class provides an implementation based on available Spring Framework components, following a similar pattern for HTTP request and response processing. The implementation incorporates logging with HTTP status codes to support troubleshooting failed revocation requests. The client class also logs an informational message when the OIDC Discovery Document does not support Token Revocation, based on the absence of the revocation_endpoint property.

Conclusion

OpenID Connect is a popular solution for managing delegated authentication, and it is also a common authentication strategy for protecting access to NiFi deployments, driving numerous feature requests and bug reports. NiFi support for Refresh Tokens improves usability with the potential for extended sessions while maintaining security through Access Tokens with short expirations. With robust token storage security and standard token revocation, the redesigned OIDC implementation supports existing integrations and enables more fine-grained access control with Authorization Servers that provide Refresh Tokens.