[ 
https://issues.apache.org/jira/browse/NIFI-14389?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pierre Villard updated NIFI-14389:
----------------------------------
    Description: 
Consider the scenario where you have InvokeHTTP with an OAuth2 Access Token 
Provider. Then the following happens:

T - Request 1 - token is acquired by the controller service with 10 minutes 
validity, request is successful in InvokeHTTP

T+X - The 3rd-party service issuing the token does not consider the token as 
valid anymore (the token service restarted, the token has been revoked, etc).

Then for the next 10-X minutes, the requests will be unauthorized AND we would 
not try to get a new access token until the token has expired.

Someone could set the refresh window property in the controller service to a 
value higher than the validity duration so that a new access token is required 
for every single request but that could be very expensive if we are processing 
a lot of requests.

Instead it would be nice to add a method in the OAuth2AccessTokenProvider 
interface allowing InvokeHTTP to force the acquisition of a new access token if 
it looks like this is needed.

Considered approach:

Add a default method in the interface:
{code:java}
    default AccessToken getAccessDetails(final boolean forceAccessTokenRefresh) 
{
        return getAccessDetails();
    }
{code}
This will not break existing implementations.

In StandardOAuth2AccessTokenProvider:
{code:java}
    @Override
    public AccessToken getAccessDetails(boolean forceAccessTokenRefresh) {
        if (forceAccessTokenRefresh) {
            acquireAccessDetails();
            return accessDetails;
        } else {
            return getAccessDetails();
        }
    }
{code}
We can then consider a specific handling in InvokeHTTP in case it is configured 
with an OAuth2AccessTokenProvider and if we receive a 401 error code.

Option 1 - have specific handling, force the refresh and send the request to 
RETRY - but that could be complicated as we may have many requests hitting 
different endpoints. Besides if the requested resource is really unauthorized, 
it means that we may always retry such request twice which is not great.

Option 2 - have specific handling, force the refresh but still send the request 
to NO_RETRY. This makes things easy and only one request would be "lost". This 
is not perfect but greatly improves the current behavior.

  was:
Consider the scenario where you have InvokeHTTP with an OAuth2 Access Token 
Provider. Then the following happens:

T - Request 1 - token is acquired by the controller service with 10 minutes 
validity, request is successful in InvokeHTTP

T+X - The 3rd-party service issuing the token does not consider the token as 
valid anymore (the token service restarted, the token has been revoked, etc).

Then for the next 10-X minutes, the requests will be unauthorized AND we would 
not try to get a new access token until the token has expired.

Someone could set the refresh window property in the controller service to a 
value higher than the validity duration so that a new access token is required 
for every single request but that could be very expensive if we are processing 
a lot of requests.

Instead it would be nice to add a method in the OAuth2AccessTokenProvider 
interface allowing InvokeHTTP to force the acquisition of a new access token if 
it looks like this is needed.

Considered approach:

Add a default method in the interface:
{code:java}
    default AccessToken getAccessDetails(final boolean forceAccessTokenRefresh) 
{
        return getAccessDetails();
    }
{code}
This will not break existing implementations.

In StandardOAuth2AccessTokenProvider:
{code:java}
    @Override
    public AccessToken getAccessDetails(boolean forceAccessTokenRefresh) {
        if (forceAccessTokenRefresh) {
            acquireAccessDetails();
            return accessDetails;
        } else {
            return getAccessDetails();
        }
    }
{code}
We can then consider a specific handling in InvokeHTTP in case it is configured 
with an OAuth2AccessTokenProvider and if we receive a 401 error code.

Option 1 - have specific handling, force the refresh and send the request to 
RETRY - but that could be complicated as we may have many requests hitting 
different endpoints. Besides if the requested resource is really unauthorized, 
it means that we may always retry such request twice which is not great.

Option 2 - have specific handling, force the refresh but still send the request 
to NO_RETRY. This makes things easy and only one request would be "lost". This 
is not perfectly but greatly improves the current behavior.


> Provide the option to force refresh Access Token in OAuth2AccessTokenProvider
> -----------------------------------------------------------------------------
>
>                 Key: NIFI-14389
>                 URL: https://issues.apache.org/jira/browse/NIFI-14389
>             Project: Apache NiFi
>          Issue Type: Improvement
>            Reporter: Pierre Villard
>            Assignee: Pierre Villard
>            Priority: Major
>
> Consider the scenario where you have InvokeHTTP with an OAuth2 Access Token 
> Provider. Then the following happens:
> T - Request 1 - token is acquired by the controller service with 10 minutes 
> validity, request is successful in InvokeHTTP
> T+X - The 3rd-party service issuing the token does not consider the token as 
> valid anymore (the token service restarted, the token has been revoked, etc).
> Then for the next 10-X minutes, the requests will be unauthorized AND we 
> would not try to get a new access token until the token has expired.
> Someone could set the refresh window property in the controller service to a 
> value higher than the validity duration so that a new access token is 
> required for every single request but that could be very expensive if we are 
> processing a lot of requests.
> Instead it would be nice to add a method in the OAuth2AccessTokenProvider 
> interface allowing InvokeHTTP to force the acquisition of a new access token 
> if it looks like this is needed.
> Considered approach:
> Add a default method in the interface:
> {code:java}
>     default AccessToken getAccessDetails(final boolean 
> forceAccessTokenRefresh) {
>         return getAccessDetails();
>     }
> {code}
> This will not break existing implementations.
> In StandardOAuth2AccessTokenProvider:
> {code:java}
>     @Override
>     public AccessToken getAccessDetails(boolean forceAccessTokenRefresh) {
>         if (forceAccessTokenRefresh) {
>             acquireAccessDetails();
>             return accessDetails;
>         } else {
>             return getAccessDetails();
>         }
>     }
> {code}
> We can then consider a specific handling in InvokeHTTP in case it is 
> configured with an OAuth2AccessTokenProvider and if we receive a 401 error 
> code.
> Option 1 - have specific handling, force the refresh and send the request to 
> RETRY - but that could be complicated as we may have many requests hitting 
> different endpoints. Besides if the requested resource is really 
> unauthorized, it means that we may always retry such request twice which is 
> not great.
> Option 2 - have specific handling, force the refresh but still send the 
> request to NO_RETRY. This makes things easy and only one request would be 
> "lost". This is not perfect but greatly improves the current behavior.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to