nifi icon indicating copy to clipboard operation
nifi copied to clipboard

NIFI-5302 Add Support for Client Credentials Flow with OIDC

Open exceptionfactory opened this issue 1 year ago • 6 comments

Summary

NIFI-5302 Adds supports for the OAuth 2.0 Client Credentials Flow when NiFi is configured for OpenID Connect authentication.

The implementation changes maintain existing support for the Authorization Code Grant Flow as part of standard browser-based access, but enable machine-to-machine authentication using Client Credentials. Most of the code changes involve reorganizing the OIDC and JWT configuration objects for reuse between configuration classes.

The configuration changes support verifying Access Tokens based on the provided Issuer claim. When the Token Issuer matches the OIDC Client Registration Issuer, NiFi uses the Identity Provider signing key for verification. In all other cases, NiFi uses the existing application signing key for verification, maintaining current behavior.

Enabling machine-to-machine access with the Client Credentials Flow may also require authorization configuration changes depending on the deployed environment. The OpenID Connect fallback claims identifying user property may also be necessary to use the sub claim as the identity instead of the default email claim. These configuration elements can be enabled using existing configuration properties and do not require additional code changes.

Tracking

Please complete the following tracking steps prior to pull request creation.

Issue Tracking

Pull Request Tracking

  • [X] Pull Request title starts with Apache NiFi Jira issue number, such as NIFI-00000
  • [X] Pull Request commit message starts with Apache NiFi Jira issue number, as such NIFI-00000

Pull Request Formatting

  • [X] Pull Request based on current revision of the main branch
  • [X] Pull Request refers to a feature branch with one commit containing changes

Verification

Please indicate the verification steps performed prior to pull request creation.

Build

  • [X] Build completed using mvn clean install -P contrib-check
    • [X] JDK 21

Licensing

  • [ ] New dependencies are compatible with the Apache License 2.0 according to the License Policy
  • [ ] New dependencies are documented in applicable LICENSE and NOTICE files

Documentation

  • [ ] Documentation formatting appears as expected in rendered files

exceptionfactory avatar Mar 19 '24 05:03 exceptionfactory

Hey @exceptionfactory - does that mean that it provides a way to use the NiFi CLI without mTLS when NiFi is configured with OIDC for Authentication? If yes, is it possible to provide examples? It also could be worth updating the documentation to reflect that option. I know it's always painful for users to leverage the CLI when both keystore and truststore are required (even if you can use the proxied entity feature).

pvillard31 avatar Mar 19 '24 08:03 pvillard31

Hey @exceptionfactory - does that mean that it provides a way to use the NiFi CLI without mTLS when NiFi is configured with OIDC for Authentication? If yes, is it possible to provide examples? It also could be worth updating the documentation to reflect that option. I know it's always painful for users to leverage the CLI when both keystore and truststore are required (even if you can use the proxied entity feature).

Thanks for asking @pvillard31.

This improvement provides the foundation for alternative authentication using the NiFi CLI, but additional work is required in the CLI itself to enable an alternative to mTLS.

I agree that mTLS can be challenging to configure for automated integration, so this pull request provides a foundation for future improvements. With this change, it will be possible to enhance the CLI to support OAuth 2 Client Credentials or Device Flow authentication. That will require additional consideration, as obtaining an Access Token often involves multiple steps. However, with these changes in place, there will be more options for integration.

I pushed a commit updating the OpenID Connect section of the Admin Guide highlighting support for the Client Credentials Grant Type and outlining the basics of the implementation.

exceptionfactory avatar Mar 19 '24 14:03 exceptionfactory

Thanks @exceptionfactory that makes sense! Can you share some details on how this can be leveraged as-is? Trying to understand how this can be tested and how this improvement would be used with NiFi deployments.

pvillard31 avatar Mar 19 '24 14:03 pvillard31

Thanks @exceptionfactory that makes sense! Can you share some details on how this can be leveraged as-is? Trying to understand how this can be tested and how this improvement would be used with NiFi deployments.

Sure, good question.

The exact details vary between Identity Providers, but the basic process for exercising this new capability is as follows:

  1. Configure an Application Client on the Identity Provider, enabled for the Client Credentials Grant Type
  2. Get the Client ID and Client Secret values associated with the Application Client from the Identity Provider
  3. Make an HTTP request to the Identity Provider requesting an Access Token using the Client ID and Client Secret values
  4. Make an HTTP request to the NiFi REST API using the access_token value returned and passing it to NiFi using the Authorization header with the Bearer scheme

The first two steps are specific to the Identity Provider configured.

Step 3 is from the OAuth 2 specification for Client Credentials as described in RFC 6749 Section 4.4.2.

Step 4 uses existing NiFi REST API handling with the HTTP Authorization header.

Here are some concrete examples for several Identity Providers on how to configure a Client Credentials Grant Flow:

Step 3 could be part of future enhancements to the NiFi CLI. For example, with an OpenID Connect Discovery URL, a Client ID, and a Client Secret, the NiFi CLI could make a request for an Access Token and then make a request to the NiFi REST API with the customized Authorization header.

As a way to test this using NiFi itself, the StandardOauth2AccessTokenProvider could be configured with the Client Credentials Grant Type, and InvokeHTTP could be used to invoke NiFi REST API methods.

This would be worth a blog post at some point, but hopefully this provides sufficient background.

exceptionfactory avatar Mar 19 '24 15:03 exceptionfactory

As mentioned in the updated documentation, testing this capability also requires the following changes:

  1. Set the property nifi.security.user.oidc.fallback.claims.identifying.user to sub so that NiFi will use the Access Token subject claim to identify users in addition to the standard email claim
  2. Add the Client ID of the Application Client to the list of users authorized to invoke NiFi REST API methods. This can be done using the standard Managed Authorizer, or other Authorize that supports multiple users.

exceptionfactory avatar Mar 19 '24 15:03 exceptionfactory

Understood, thanks, will give it a try asap if no one else can do it before.

pvillard31 avatar Mar 19 '24 16:03 pvillard31

Rebased to incorporate latest updates to Spring Framework 6.1. Replaced deprecated OkHttp3ClientHttpRequestFactory with JdkClientHttpRequestFactory.

exceptionfactory avatar Apr 09 '24 02:04 exceptionfactory

Hi @exceptionfactory , I have tested your branch with my test Keycloak server and my group authorization configs. And it works as expected. I can make calls to Nifi REST API with token from client credentials flow.

Add the Client ID of the Application Client to the list of users authorized to invoke NiFi REST API methods.

I'd like to added that, to make the Nifi REST API access works properly, the username added to NiFi's list of users authorized need to have the same name as the sub value of Token subject claim. This part is not clear to me when I first tried it.

raditpan avatar Apr 25 '24 06:04 raditpan

Thanks for the feedback @raditpan! Glad to hear it works as expected.

You are correct that the Client ID from the sub claim needs to be authorized, which follows the pattern of other authentication strategies such as client certificates, where the certificate subject needs to be authorized for invoking REST API resources.

exceptionfactory avatar Apr 25 '24 15:04 exceptionfactory