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

humpfhumpf updated NIFI-7771:
-----------------------------
    Description: 
h2. Context

Before the bug occurs, it needs:
 * One load-balancer which uses client IP affinity to “select” one NiFi 
instance in the cluster;
 * One fresh and successful OpenID Connect authentication on WebUI.

Then, stops the NiFi instance, which was “selected” by the load-balancer for 
you.

WebUI (javascript) continues to poll WebAPI by fetching status URLs, but all 
calls return HTTP 401 error. Then WebUI shows an error screen: “Unauthorized. 
Unable to validate the access token.”, with 2 links: “log out” and “home”.

If you click on the “home” link, *the browser enters in an infinite loop of 
redirects between NiFi and OIDC Identity Provider.*

The offending HTTP flows is:
 * “home” link calls: GET /nifi
 * Redirects to: GET /nifi/
 ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
 * Redirects to: GET /nifi/login
 * Redirects to: GET <my_idp_url>/openid-connect/auth
 * Redirects to: GET /nifi-api/access/oidc/callback
 * Redirects to: GET /nifi
 * Redirects to: GET /nifi/
 ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
 * [loop]

 

The stack trace of {{/nifi-api/flow/current-user}} call is:

 
{code:java}
ERROR [NiFi Web Server-284] o.a.nifi.web.security.jwt.JwtService There was an 
error validating the JWT io.jsonwebtoken.JwtException: Unable to validate the 
access token.
         at 
org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:106)
         at 
org.apache.nifi.web.security.jwt.JwtService.getAuthenticationFromToken(JwtService.java:60)
         at 
org.apache.nifi.web.security.jwt.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:48)
         at 
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:78)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
         at 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:99)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
         ...
Caused by: io.jsonwebtoken.SignatureException: JWT signature does not match 
locally computed signature. JWT validity cannot be asserted and should not be 
trusted.
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:342)
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518)
         at 
org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:102)
         ...
{code}
 

 

In my opinion, there are 2 problems:
h2. Problem 1

The NiFi JWT token is used (and not replaced) by nfCanvas.init() even after 
loadCurrentUser() failed with an authentication error (when GET 
/nifi-api/flow/current-user returns 401).

In such case, this token, stored in nfStorage (in Javascript Local Storage of 
browser), should be cleared before redirecting to /nifi/login.
h2. Problem 2

The NiFi JWT token is not shared among NiFi cluster.

This token is not the original id_token returned by the OIDC Identity Provider, 
but a new one, generated by the NiFi instance on which the browser was routed 
during the OIDC connection flow.

This token is closely related to some data stored in H2 users database 
(nifi-user-keys.h2.db).

Its “KEY” table contains the following data for each user: email, a primary key 
(auto increment) and a generated UUID.

The NiFi JWT token contains (among other things) a copy of email and the 
auto-incremented primary key. Moreover, this JWT is HS256-signed with UUID key.

*But, both primary key and UUID are not shared in NiFi cluster.*

It seems to be the reason why WebUI must interrupt its polling to WebAPI: 
stored JWT is no more valid on the new “selected” NiFi instance, to which the 
load-balancer routes your browser.

I think there are 3 solutions:
 * Use a shared secret (from a new property in nifi.properties) to sign NiFi 
JWT tokens. The uselessness of the primary key inside the token should be 
checked;
 * Synchronize the H2 users database among NiFi cluster;
 * Replace the NiFi interal JWT token by the official OIDC JWT “id_token” on 
every WebAPI call.

 

  was:
h2. Context

Before the bug occurs, it needs:
 * One load-balancer which uses client IP affinity to “select” one NiFi 
instance in the cluster;
 * One fresh and successful OpenID Connect authentication on WebUI.

Then, stops the NiFi instance, which was “selected” by the load-balancer for 
you.

WebUI (javascript) continues to poll WebAPI by fetching status URLs, but all 
calls return HTTP 401 error. Then WebUI shows an error screen: “Unauthorized. 
Unable to validate the access token.”, with 2 links: “log out” and “home”.

If you click on the “home” link, *the browser enters in an infinite loop of 
redirects between NiFi and OIDC Identity Provider.*

The offending HTTP flows is:
 * “home” link calls: GET /nifi
 * Redirects to: GET /nifi/
 ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
 * Redirects to: GET /nifi/login
 * Redirects to: GET <my_idp_url>/openid-connect/auth
 * Redirects to: GET /nifi-api/access/oidc/callback
 * Redirects to: GET /nifi
 * Redirects to: GET /nifi/
 ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
 * [loop]

 

The stack trace of {{/nifi-api/flow/current-user}} call is:

 
{code:java}
ERROR [NiFi Web Server-284] o.a.nifi.web.security.jwt.JwtService There was an 
error validating the JWT io.jsonwebtoken.JwtException: Unable to validate the 
access token.
         at 
org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:106)
         at 
org.apache.nifi.web.security.jwt.JwtService.getAuthenticationFromToken(JwtService.java:60)
         at 
org.apache.nifi.web.security.jwt.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:48)
         at 
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:78)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
         at 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:99)
         at 
org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
         ...
Caused by: io.jsonwebtoken.SignatureException: JWT signature does not match 
locally computed signature. JWT validity cannot be asserted and should not be 
trusted.
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:342)
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
         at 
io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518)
         at 
org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:102)
         ...
{code}
 

 

In my opinion, there are 2 problems:
h2. Problem 1

The NiFi JWT token is used (and not replaced) by nfCanvas.init() even after 
loadCurrentUser() failed with an authentication error (when GET 
/nifi-api/flow/current-user returns 401).

In such case, this token, stored in nfStorage (in Javascript Local Storage of 
browser), should be cleared before redirecting to /nifi/login.
h2. Problem 2

The NiFi JWT token is not shared among NiFi cluster.

This token is not the original id_token returned by the OIDC Identity Provider, 
but a new one, generated by the NiFi instance on which your browser was routed 
during the OIDC connection flow.

This token is closely related to some data stored in H2 users database 
(nifi-user-keys.h2.db).

Its “KEY” table contains the following data for each user: email, a primary key 
(auto increment) and a generated UUID.

The NiFi JWT token contains (among other things) a copy of email and the 
auto-incremented primary key. Moreover, this JWT is HS256-signed with UUID key.

*But, both primary key and UUID are not shared in NiFi cluster.*

It seems to be the reason why WebUI must interrupt its polling to WebAPI: 
stored JWT is no more valid on the new “selected” NiFi instance, to which the 
load-balancer routes your browser.

I think there are 3 solutions:
 * Use a shared secret (from a new property in nifi.properties) to sign NiFi 
JWT tokens. The uselessness of the primary key inside the token should be 
checked;
 * Synchronize the H2 users database among NiFi cluster;
 * Replace the NiFi interal JWT token by the official OIDC JWT “id_token” on 
every WebAPI call.

 


> Infinite loop on WebUI when node stopped in cluster
> ---------------------------------------------------
>
>                 Key: NIFI-7771
>                 URL: https://issues.apache.org/jira/browse/NIFI-7771
>             Project: Apache NiFi
>          Issue Type: Bug
>          Components: Core UI
>    Affects Versions: 1.10.0, 1.9.2, 1.12.0, 1.11.4
>         Environment: Linux
>            Reporter: humpfhumpf
>            Priority: Critical
>
> h2. Context
> Before the bug occurs, it needs:
>  * One load-balancer which uses client IP affinity to “select” one NiFi 
> instance in the cluster;
>  * One fresh and successful OpenID Connect authentication on WebUI.
> Then, stops the NiFi instance, which was “selected” by the load-balancer for 
> you.
> WebUI (javascript) continues to poll WebAPI by fetching status URLs, but all 
> calls return HTTP 401 error. Then WebUI shows an error screen: “Unauthorized. 
> Unable to validate the access token.”, with 2 links: “log out” and “home”.
> If you click on the “home” link, *the browser enters in an infinite loop of 
> redirects between NiFi and OIDC Identity Provider.*
> The offending HTTP flows is:
>  * “home” link calls: GET /nifi
>  * Redirects to: GET /nifi/
>  ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
>  * Redirects to: GET /nifi/login
>  * Redirects to: GET <my_idp_url>/openid-connect/auth
>  * Redirects to: GET /nifi-api/access/oidc/callback
>  * Redirects to: GET /nifi
>  * Redirects to: GET /nifi/
>  ** asynchronously calls: GET /nifi-api/flow/current-user => failed HTTP 401
>  * [loop]
>  
> The stack trace of {{/nifi-api/flow/current-user}} call is:
>  
> {code:java}
> ERROR [NiFi Web Server-284] o.a.nifi.web.security.jwt.JwtService There was an 
> error validating the JWT io.jsonwebtoken.JwtException: Unable to validate the 
> access token.
>          at 
> org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:106)
>          at 
> org.apache.nifi.web.security.jwt.JwtService.getAuthenticationFromToken(JwtService.java:60)
>          at 
> org.apache.nifi.web.security.jwt.JwtAuthenticationProvider.authenticate(JwtAuthenticationProvider.java:48)
>          at 
> org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
>          at 
> org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:78)
>          at 
> org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
>          at 
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
>          at 
> org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:99)
>          at 
> org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:58)
>          ...
> Caused by: io.jsonwebtoken.SignatureException: JWT signature does not match 
> locally computed signature. JWT validity cannot be asserted and should not be 
> trusted.
>          at 
> io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:342)
>          at 
> io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
>          at 
> io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:518)
>          at 
> org.apache.nifi.web.security.jwt.JwtService.parseTokenFromBase64EncodedString(JwtService.java:102)
>          ...
> {code}
>  
>  
> In my opinion, there are 2 problems:
> h2. Problem 1
> The NiFi JWT token is used (and not replaced) by nfCanvas.init() even after 
> loadCurrentUser() failed with an authentication error (when GET 
> /nifi-api/flow/current-user returns 401).
> In such case, this token, stored in nfStorage (in Javascript Local Storage of 
> browser), should be cleared before redirecting to /nifi/login.
> h2. Problem 2
> The NiFi JWT token is not shared among NiFi cluster.
> This token is not the original id_token returned by the OIDC Identity 
> Provider, but a new one, generated by the NiFi instance on which the browser 
> was routed during the OIDC connection flow.
> This token is closely related to some data stored in H2 users database 
> (nifi-user-keys.h2.db).
> Its “KEY” table contains the following data for each user: email, a primary 
> key (auto increment) and a generated UUID.
> The NiFi JWT token contains (among other things) a copy of email and the 
> auto-incremented primary key. Moreover, this JWT is HS256-signed with UUID 
> key.
> *But, both primary key and UUID are not shared in NiFi cluster.*
> It seems to be the reason why WebUI must interrupt its polling to WebAPI: 
> stored JWT is no more valid on the new “selected” NiFi instance, to which the 
> load-balancer routes your browser.
> I think there are 3 solutions:
>  * Use a shared secret (from a new property in nifi.properties) to sign NiFi 
> JWT tokens. The uselessness of the primary key inside the token should be 
> checked;
>  * Synchronize the H2 users database among NiFi cluster;
>  * Replace the NiFi interal JWT token by the official OIDC JWT “id_token” on 
> every WebAPI call.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to